1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-15 00:29:49 +02:00

calculate time of next trustdb check

This commit is contained in:
Werner Koch 2001-09-28 17:00:00 +00:00
parent aa971d5c89
commit ebf6b8a515
29 changed files with 14188 additions and 13912 deletions

2
NEWS
View File

@ -49,6 +49,8 @@
* --trusted-keys is again obsolete, --edit can be used to set the
ownertrust of any key to ultimately trusted.
* A subkey is never used to sign keys.
Noteworthy changes in version 1.0.6 (2001-05-29)
------------------------------------------------

2
TODO
View File

@ -4,8 +4,6 @@
* Selection using +wordlist does not work.
* Always use the primary key to sign other keys.
* add listing of notation data
* Check the changes to the gpg random gatherer on all W32 platforms.

View File

@ -1,3 +1,7 @@
2001-09-28 Werner Koch <wk@gnupg.org>
* gpg.sgml: Add a note on option parsing.
2001-09-24 Werner Koch <wk@gnupg.org>
* gpg.sgml: Described --{update,check}-trustdb.

View File

@ -77,6 +77,10 @@ For a more verbose documentation get the GNU Privacy Handbook (GPH), which is
available at http://www.gnupg.org/gph/ .
You will find a list of HOWTO documents at http://www.gnupg.org/docs.html .
</para>
<para>
Please remember that option parsing stops as soon as a non option is
encountered, you can explicitly stop option parsing by using the
special option "--".
</refsect1>
<refsect1>
@ -504,10 +508,7 @@ not be expected to successfully import such a key.
<term>--fast-import &OptParmFiles;</term>
<listitem><para>
Import/merge keys. This adds the given keys to the
keyring.
The fast version does not update
the trustdb; this can be done at any time with the
command --update-trustdb.
keyring. The fast version is currently just a synonym.
</para>
<para>
There are a few other options which control how this command works.
@ -554,6 +555,11 @@ 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>
<para>
For use with cron jobs, this command can be used together with --batch
in which case the check is only done when it is due. To force a run
even in batch mode add the option --yes.
</para></listitem></varlistentry>

View File

@ -26,6 +26,10 @@ For a more verbose documentation get the GNU Privacy Handbook (GPH), which is
available at http://www.gnupg.org/gph/ .
You will find a list of HOWTO documents at http://www.gnupg.org/docs.html .
Please remember that option parsing stops as soon as a non option is
encountered, you can explicitly stop option parsing by using the
special option "---".
@majorheading COMMANDS
@code{gpg} recognizes these commands:

View File

@ -1,5 +1,18 @@
2001-09-28 Werner Koch <wk@gnupg.org>
* keyedit.c (sign_uids): Always use the primary key to sign keys.
* getkey.c (finish_lookup): Hack to return only the primary key if
a certification key has been requested.
* trustdb.c (cmp_kid_for_make_key_array): Renamed to
(validate_one_keyblock): this and changed arg for direct calling.
(make_key_array): Renamed to
(validate_one_keyblock): this and changed args for direct calling.
(mark_usable_uid_certs, validate_one_keyblock)
(validate_key_list): Add next_expire arg to keep track of
expiration times.
(validate_keys): Ditto for UTKs and write the stamp.
* tdbio.c (migrate_from_v2): Check return code of tbdio_sync.
* tdbdump.c (import_ownertrust): Do a tdbio_sync().

View File

@ -1110,6 +1110,8 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
uid->help_key_usage |= PUBKEY_USAGE_SIG;
if ( (*p & 12) )
uid->help_key_usage |= PUBKEY_USAGE_ENC;
/* Note: we do not set the CERT flag here because it can be assumed
* that thre is no real policy to set it. */
}
/* ditto or the key expiration */
@ -1656,7 +1658,7 @@ merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
* secret subkey is avalable and deletes the public subkey otherwise.
* We need this function because we can't delete it later when we
* actually merge the secret parts into the pubring.
& The function also plays some games with the node flags.
* The function also plays some games with the node flags.
*/
static void
premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
@ -1754,6 +1756,7 @@ finish_lookup (GETKEY_CTX ctx)
PKT_user_id *foundu = NULL;
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC)
unsigned int req_usage = ( ctx->req_usage & USAGE_MASK );
int req_cert = (ctx->req_usage & PUBKEY_USAGE_CERT);
u32 latest_date;
KBNODE latest_key;
u32 curtime = make_timestamp ();
@ -1803,7 +1806,8 @@ finish_lookup (GETKEY_CTX ctx)
latest_date = 0;
latest_key = NULL;
if ( !foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
/* do not look at subkeys if a certification key is requested */
if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_cert) {
KBNODE nextk;
/* either start a loop or check just this one subkey */
for (k=foundk?foundk:keyblock; k; k = nextk ) {
@ -1854,11 +1858,11 @@ finish_lookup (GETKEY_CTX ctx)
}
}
/* Okay now try the primary key unless we have want an exact
/* Okay now try the primary key unless we want an exact
* key ID match on a subkey */
if ( !latest_key && !(ctx->exact && foundk != keyblock) ) {
if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_cert) {
PKT_public_key *pk;
if (DBG_CACHE && !foundk )
if (DBG_CACHE && !foundk && !req_cert )
log_debug( "\tno suitable subkeys found - trying primary\n");
pk = keyblock->pkt->pkt.public_key;
if ( !pk->is_valid ) {

View File

@ -253,8 +253,14 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
int select_all = !count_selected_uids(keyblock);
int upd_trust = 0;
/* build a list of all signators */
rc=build_sk_list( locusr, &sk_list, 0, 1 );
/* build a list of all signators.
*
* We use the CERT flag to request the primary which must always
* be one which is capable of signing keys. I can't see a reason
* why to sign keys using a subkey. Implementation of SUAGE_CERT
* is just a hack in getkey.c and does not mean that a subkey
* marked as certification capable will be used */
rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT);
if( rc )
goto leave;

View File

@ -121,6 +121,15 @@ list_one( STRLIST names, int secret )
KBNODE keyblock = NULL;
GETKEY_CTX ctx;
/* fixme: using the bynames function has the disadvantage that we
* don't knowether one of the names given was not found. OTOH,
* this function has the advantage to list the names in the
* sequence as defined by the keyDB and does not duplicate
* outputs. A solution could be do test whether all given have
* been listed (this needs a way to use the keyDB search
* functions) or to have the search function return indicators for
* found names. Yet another way is to use the keydb search
* facilities directly. */
if( secret ) {
rc = get_seckey_bynames( &ctx, NULL, names, &keyblock );
if( rc ) {

View File

@ -102,6 +102,7 @@ new_offset_item (void)
return k;
}
#if 0
static void
release_offset_items (struct off_item *k)
{
@ -113,7 +114,7 @@ release_offset_items (struct off_item *k)
m_free (k);
}
}
#endif
static OffsetHashTable
new_offset_hash_table (void)

View File

@ -82,8 +82,8 @@ is_duplicated_entry (STRLIST list, STRLIST item)
int
build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
unsigned use )
build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
int unlock, unsigned int use )
{
SK_LIST sk_list = NULL;
int rc;

View File

@ -452,12 +452,33 @@ trust_letter (unsigned int value)
/****************
* Recreate the WoT but do not ask for new ownertrusts
* Recreate the WoT but do not ask for new ownertrusts. Special
* feature: In batch mode and without a forced yes, this is only done
* when a check is due. This can be used to run the check from a crontab
*/
void
check_trustdb()
check_trustdb ()
{
init_trustdb();
if (opt.batch && !opt.answer_yes)
{
ulong scheduled;
scheduled = tdbio_read_nextcheck ();
if (!scheduled)
{
log_info (_("no need for a trustdb check\n"));
return;
}
if (scheduled > make_timestamp ())
{
log_info (_("next trustdb check due at %s\n"),
strtimestamp (scheduled));
return;
}
}
validate_keys (0);
}
@ -865,116 +886,6 @@ mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
}
static int
search_skipfnc (void *opaque, u32 *kid)
{
return test_key_hash_table ((KeyHashTable)opaque, kid);
}
/*
* Scan all keys and return a key_array of all keys which are
* indicated as found by the supplied CMPFNC. The caller has to pass
* a keydb handle so that we don't use to create our own. Returns
* either a key_array or NULL in case of an error. No results found
* are indicated by an empty array. Caller hast to release the
* returned array.
*/
static struct key_array *
make_key_array (KEYDB_HANDLE hd, KeyHashTable visited,
int (*cmpfnc)(KBNODE kb, void *opaque), void *cmpval)
{
KBNODE keyblock = NULL;
struct key_array *keys = NULL;
size_t nkeys, maxkeys;
int rc;
KEYDB_SEARCH_DESC desc;
maxkeys = 1000;
keys = m_alloc ((maxkeys+1) * sizeof *keys);
nkeys = 0;
rc = keydb_search_reset (hd);
if (rc)
{
log_error ("keydb_search_reset failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST;
desc.skipfnc = search_skipfnc;
desc.skipfncvalue = visited;
rc = keydb_search (hd, &desc, 1);
if (rc == -1)
{
keys[nkeys].keyblock = NULL;
return keys;
}
if (rc)
{
log_error ("keydb_search_first failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
do
{
PKT_public_key *pk;
rc = keydb_get_keyblock (hd, &keyblock);
if (rc)
{
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
{
log_debug ("ooops: invalid pkttype %d encountered\n",
keyblock->pkt->pkttype);
dump_kbnode (keyblock);
release_kbnode(keyblock);
continue;
}
/* prepare the keyblock for further processing */
merge_keys_and_selfsig (keyblock);
clear_kbnode_flags (keyblock);
pk = keyblock->pkt->pkt.public_key;
if (pk->has_expired || pk->is_revoked)
{
/* it does not make sense to look further at those keys */
mark_keyblock_seen (visited, keyblock);
}
else if (cmpfnc (keyblock, cmpval))
{
if (nkeys == maxkeys) {
maxkeys += 1000;
keys = m_realloc (keys, (maxkeys+1) * sizeof *keys);
}
keys[nkeys++].keyblock = keyblock;
/* This key is signed - don't check it again */
mark_keyblock_seen (visited, keyblock);
}
else
release_kbnode (keyblock);
keyblock = NULL;
}
while ( !(rc = keydb_search (hd, &desc, 1)) );
if (rc && rc != -1)
{
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
keys[nkeys].keyblock = NULL;
return keys;
}
static void
dump_key_array (int depth, struct key_array *keys)
@ -1077,7 +988,8 @@ is_in_klist (struct key_item *k, PKT_signature *sig)
*/
static void
mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
u32 *main_kid, struct key_item *klist, u32 curtime)
u32 *main_kid, struct key_item *klist,
u32 curtime, u32 *next_expire)
{
KBNODE node;
PKT_signature *sig = node->pkt->pkt.signature;
@ -1157,12 +1069,16 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
* system falls back to an older certification which has a
* different expiration time */
const byte *p;
u32 expire;
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
if ( p && (sig->timestamp + buffer_to_u32(p)) >= curtime )
; /* signature expired */
else
signode->flag |= (1<<8); /* yeah eventually we found a good cert */
expire = p? sig->timestamp + buffer_to_u32(p) : 0;
if ( expire < curtime )
{
signode->flag |= (1<<8); /* yeah, found a good cert */
if (expire && expire < *next_expire)
*next_expire = expire;
}
}
}
}
@ -1181,9 +1097,8 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
* This function assumes that all kbnode flags are cleared on entry.
*/
static int
cmp_kid_for_make_key_array (KBNODE kb, void *opaque)
validate_one_keyblock (KBNODE kb, struct key_item *klist, u32 *next_expire)
{
struct key_item *klist = opaque;
struct key_item *kr;
KBNODE node, uidnode=NULL;
PKT_public_key *pk = kb->pkt->pkt.public_key;
@ -1209,7 +1124,8 @@ cmp_kid_for_make_key_array (KBNODE kb, void *opaque)
uidnode = node;
issigned = 0;
fully_count = marginal_count = 0;
mark_usable_uid_certs (kb, uidnode, main_kid, klist, curtime);
mark_usable_uid_certs (kb, uidnode, main_kid, klist,
curtime, next_expire);
}
else if (node->pkt->pkttype == PKT_SIGNATURE
&& (node->flag & (1<<8)) )
@ -1245,6 +1161,120 @@ cmp_kid_for_make_key_array (KBNODE kb, void *opaque)
}
static int
search_skipfnc (void *opaque, u32 *kid)
{
return test_key_hash_table ((KeyHashTable)opaque, kid);
}
/*
* Scan all keys and return a key_array of all suitable keys from
* kllist. The caller has to pass keydb handle so that we don't use
* to create our own. Returns either a key_array or NULL in case of
* an error. No results found are indicated by an empty array.
* Caller hast to release the returned array.
*/
static struct key_array *
validate_key_list (KEYDB_HANDLE hd, KeyHashTable visited,
struct key_item *klist, u32 *next_expire)
{
KBNODE keyblock = NULL;
struct key_array *keys = NULL;
size_t nkeys, maxkeys;
int rc;
KEYDB_SEARCH_DESC desc;
maxkeys = 1000;
keys = m_alloc ((maxkeys+1) * sizeof *keys);
nkeys = 0;
rc = keydb_search_reset (hd);
if (rc)
{
log_error ("keydb_search_reset failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST;
desc.skipfnc = search_skipfnc;
desc.skipfncvalue = visited;
rc = keydb_search (hd, &desc, 1);
if (rc == -1)
{
keys[nkeys].keyblock = NULL;
return keys;
}
if (rc)
{
log_error ("keydb_search_first failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
do
{
PKT_public_key *pk;
rc = keydb_get_keyblock (hd, &keyblock);
if (rc)
{
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
{
log_debug ("ooops: invalid pkttype %d encountered\n",
keyblock->pkt->pkttype);
dump_kbnode (keyblock);
release_kbnode(keyblock);
continue;
}
/* prepare the keyblock for further processing */
merge_keys_and_selfsig (keyblock);
clear_kbnode_flags (keyblock);
pk = keyblock->pkt->pkt.public_key;
if (pk->has_expired || pk->is_revoked)
{
/* it does not make sense to look further at those keys */
mark_keyblock_seen (visited, keyblock);
}
else if (validate_one_keyblock (keyblock, klist, next_expire))
{
if (pk->expiredate && pk->expiredate < *next_expire)
*next_expire = pk->expiredate;
if (nkeys == maxkeys) {
maxkeys += 1000;
keys = m_realloc (keys, (maxkeys+1) * sizeof *keys);
}
keys[nkeys++].keyblock = keyblock;
/* this key is signed - don't check it again */
mark_keyblock_seen (visited, keyblock);
keyblock = NULL;
}
release_kbnode (keyblock);
keyblock = NULL;
}
while ( !(rc = keydb_search (hd, &desc, 1)) );
if (rc && rc != -1)
{
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
m_free (keys);
return NULL;
}
keys[nkeys].keyblock = NULL;
return keys;
}
/*
* Run the key validation procedure.
*
@ -1283,6 +1313,7 @@ validate_keys (int interactive)
int key_count;
int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate;
KeyHashTable visited;
u32 next_expire;
visited = new_key_hash_table ();
/* Fixme: Instead of always building a UTK list, we could just build it
@ -1293,10 +1324,13 @@ validate_keys (int interactive)
goto leave;
}
next_expire = 0xffffffff; /* set next expire to the year 2106 */
/* mark all UTKs as visited and set validity to ultimate */
for (k=utk_list; k; k = k->next)
{
KBNODE keyblock;
PKT_public_key *pk;
keyblock = get_pubkeyblock (k->kid);
if (!keyblock)
@ -1306,6 +1340,7 @@ validate_keys (int interactive)
continue;
}
mark_keyblock_seen (visited, keyblock);
pk = keyblock->pkt->pkt.public_key;
for (node=keyblock; node; node = node->next)
{
if (node->pkt->pkttype == PKT_USER_ID)
@ -1317,10 +1352,12 @@ validate_keys (int interactive)
rmd160_hash_buffer (namehash, uid->photo, uid->photolen);
else
rmd160_hash_buffer (namehash, uid->name, uid->len );
update_validity (keyblock->pkt->pkt.public_key,
namehash, 0, TRUST_ULTIMATE);
update_validity (pk, namehash, 0, TRUST_ULTIMATE);
}
}
if ( pk->expiredate && pk->expiredate < next_expire)
next_expire = pk->expiredate;
release_kbnode (keyblock);
do_sync ();
}
@ -1355,10 +1392,10 @@ validate_keys (int interactive)
}
/* Find all keys which are signed by a key in kdlist */
keys = make_key_array (kdb, visited, cmp_kid_for_make_key_array, klist);
keys = validate_key_list (kdb, visited, klist, &next_expire);
if (!keys)
{
log_error ("make_key_array failed\n");
log_error ("validate_key_list failed\n");
rc = G10ERR_GENERAL;
goto leave;
}
@ -1413,7 +1450,14 @@ validate_keys (int interactive)
release_key_hash_table (visited);
if (!rc) /* mark trustDB as checked */
{
tdbio_write_nextcheck (0);
if (next_expire == 0xffffffff)
tdbio_write_nextcheck (0);
else
{
tdbio_write_nextcheck (next_expire);
log_info (_("next trustdb check due at %s\n"),
strtimestamp (next_expire));
}
do_sync ();
}
return rc;

View File

@ -1,3 +1,7 @@
2001-09-28 Werner Koch <wk@gnupg.org>
* cipher.h (PUBKEY_USAGE_CERT): New.
2001-09-07 Werner Koch <wk@gnupg.org>
* util.h: Add strsep().

View File

@ -50,6 +50,7 @@
#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
#define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/
#define DIGEST_ALGO_MD5 1
#define DIGEST_ALGO_SHA1 2

1636
po/da.po

File diff suppressed because it is too large Load Diff

1888
po/de.po

File diff suppressed because it is too large Load Diff

1855
po/eo.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1855
po/et.po

File diff suppressed because it is too large Load Diff

1877
po/fr.po

File diff suppressed because it is too large Load Diff

1857
po/id.po

File diff suppressed because it is too large Load Diff

1865
po/it.po

File diff suppressed because it is too large Load Diff

1854
po/ja.po

File diff suppressed because it is too large Load Diff

1862
po/nl.po

File diff suppressed because it is too large Load Diff

1865
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1874
po/sv.po

File diff suppressed because it is too large Load Diff

1859
po/tr.po

File diff suppressed because it is too large Load Diff