mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
See ChangeLog: Wed Feb 10 17:15:39 CET 1999 Werner Koch
This commit is contained in:
parent
a16e15282a
commit
9a4f506a18
60 changed files with 2006 additions and 1340 deletions
|
@ -1,3 +1,25 @@
|
|||
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* g10.c (main): check for development version now in configure
|
||||
|
||||
* tdbio.c (tdbio_write_record): Add uid.validity
|
||||
(tdbio_read_record) : Ditto.
|
||||
(tdbio_dump_record) : Ditto.
|
||||
|
||||
* keygen.c (keygen_add_std_prefs): Replaced Blowfish by Twofish,
|
||||
removed MD5 and Tiger.
|
||||
* pubkey-enc.c (get_it): Suppress warning about missing Blowfish
|
||||
in preferences in certain cases.
|
||||
|
||||
* ringedit.c (lock_rentry,unlock_rentry): New.
|
||||
|
||||
* getkey.c (key_byname): Pass ret_kb down to lookup_xx.
|
||||
|
||||
* armor.c (armor_filter): No output of of empty comment lines.
|
||||
Add option --no-version to suppress the output of the version string.
|
||||
|
||||
* getkey.c: Release the getkey context for auto context variables.
|
||||
|
||||
Sun Jan 24 18:16:26 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
|
||||
|
||||
* getkey.c: Changed the internal design to allow simultaneous
|
||||
|
|
29
g10/armor.c
29
g10/armor.c
|
@ -876,23 +876,26 @@ armor_filter( void *opaque, int control,
|
|||
iobuf_writestr(a, "-----");
|
||||
iobuf_writestr(a, head_strings[afx->what] );
|
||||
iobuf_writestr(a, "-----\n");
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")\n");
|
||||
if( !opt.no_version )
|
||||
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")\n");
|
||||
|
||||
if( opt.comment_string ) {
|
||||
const char *s = opt.comment_string;
|
||||
iobuf_writestr(a, "Comment: " );
|
||||
for( ; *s; s++ ) {
|
||||
if( *s == '\n' )
|
||||
iobuf_writestr(a, "\\n" );
|
||||
else if( *s == '\r' )
|
||||
iobuf_writestr(a, "\\r" );
|
||||
else if( *s == '\v' )
|
||||
iobuf_writestr(a, "\\v" );
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
if( *s ) {
|
||||
iobuf_writestr(a, "Comment: " );
|
||||
for( ; *s; s++ ) {
|
||||
if( *s == '\n' )
|
||||
iobuf_writestr(a, "\\n" );
|
||||
else if( *s == '\r' )
|
||||
iobuf_writestr(a, "\\r" );
|
||||
else if( *s == '\v' )
|
||||
iobuf_writestr(a, "\\v" );
|
||||
else
|
||||
iobuf_put(a, *s );
|
||||
}
|
||||
iobuf_put(a, '\n' );
|
||||
}
|
||||
iobuf_put(a, '\n' );
|
||||
}
|
||||
else
|
||||
iobuf_writestr(a,
|
||||
|
|
12
g10/g10.c
12
g10/g10.c
|
@ -117,6 +117,7 @@ enum cmd_and_opt_values { aNull = 0,
|
|||
oDebugAll,
|
||||
oStatusFD,
|
||||
oNoComment,
|
||||
oNoVersion,
|
||||
oCompletesNeeded,
|
||||
oMarginalsNeeded,
|
||||
oMaxCertDepth,
|
||||
|
@ -307,6 +308,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||
{ oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
|
||||
{ oSetFilename, "set-filename", 2, "@" },
|
||||
{ oComment, "comment", 2, "@" },
|
||||
{ oNoVersion, "no-version", 0, "@"},
|
||||
{ oNotDashEscaped, "not-dash-escaped", 0, "@" },
|
||||
{ oEscapeFrom, "escape-from-lines", 0, "@" },
|
||||
{ oLockOnce, "lock-once", 0, "@" },
|
||||
|
@ -716,6 +718,7 @@ main( int argc, char **argv )
|
|||
opt.verbose = 0; opt.list_sigs=0; break;
|
||||
case oQuickRandom: quick_random_gen(1); break;
|
||||
case oNoComment: opt.no_comment=1; break;
|
||||
case oNoVersion: opt.no_version=1; break;
|
||||
case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
|
||||
case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
|
||||
case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
|
||||
|
@ -810,6 +813,9 @@ main( int argc, char **argv )
|
|||
if( greeting ) {
|
||||
tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
|
||||
tty_printf("%s\n", strusage(15) );
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
|
||||
|
@ -859,12 +865,6 @@ main( int argc, char **argv )
|
|||
log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
|
||||
}
|
||||
|
||||
{ const char *p = strusage(13);
|
||||
for( ; *p && (isdigit(*p) || *p=='.'); p++ )
|
||||
;
|
||||
if( *p )
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
}
|
||||
|
||||
if( log_get_errorcount(0) )
|
||||
g10_exit(2);
|
||||
|
|
37
g10/getkey.c
37
g10/getkey.c
|
@ -38,9 +38,9 @@
|
|||
#define MAX_PK_CACHE_ENTRIES 50
|
||||
#define MAX_UID_CACHE_ENTRIES 50
|
||||
|
||||
/* Aa map of the all characters valid used for word_match()
|
||||
/* A map of the all characters valid used for word_match()
|
||||
* Valid characters are in in this table converted to uppercase.
|
||||
* becuase the upper 128 bytes have special meanin, we assume
|
||||
* because the upper 128 bytes have special meaning, we assume
|
||||
* that they are all valid.
|
||||
* Note: We must use numerical values here in case that this program
|
||||
* will be converted to those little blue HAL9000s with their strange
|
||||
|
@ -95,6 +95,7 @@ struct getkey_ctx_s {
|
|||
KBPOS kbpos;
|
||||
int last_rc;
|
||||
ulong count;
|
||||
int not_allocated;
|
||||
int nitems;
|
||||
getkey_item_t items[1];
|
||||
};
|
||||
|
@ -322,11 +323,13 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
|
|||
/* do a lookup */
|
||||
{ struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_pk( &ctx, pk, NULL );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
if( !rc )
|
||||
goto leave;
|
||||
|
@ -371,11 +374,13 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
|
|||
struct getkey_ctx_s ctx;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
if( !rc ) {
|
||||
/* check the secret key (this may prompt for a passprase to
|
||||
* unlock the secret key
|
||||
|
@ -395,14 +400,18 @@ int
|
|||
get_primary_seckey( PKT_secret_key *sk, u32 *keyid )
|
||||
{
|
||||
struct getkey_ctx_s ctx;
|
||||
int rc;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.primary = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
return lookup_sk( &ctx, sk, NULL );
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -421,11 +430,13 @@ seckey_available( u32 *keyid )
|
|||
|
||||
sk = m_alloc_clear( sizeof *sk );
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 11;
|
||||
ctx.items[0].keyid[0] = keyid[0];
|
||||
ctx.items[0].keyid[1] = keyid[1];
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
free_secret_key( sk );
|
||||
return rc;
|
||||
}
|
||||
|
@ -653,9 +664,9 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
|||
/* and call the lookup function */
|
||||
ctx->primary = 1; /* we want to look for the primary key only */
|
||||
if( sk )
|
||||
rc = lookup_sk( ctx, sk, NULL );
|
||||
rc = lookup_sk( ctx, sk, ret_kb );
|
||||
else
|
||||
rc = lookup_pk( ctx, pk, NULL );
|
||||
rc = lookup_pk( ctx, pk, ret_kb );
|
||||
|
||||
if( retctx ) /* caller wants the context */
|
||||
*retctx = ctx;
|
||||
|
@ -733,7 +744,8 @@ get_pubkey_end( GETKEY_CTX ctx )
|
|||
enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */
|
||||
for(n=0; n < ctx->nitems; n++ )
|
||||
m_free( ctx->items[n].namebuf );
|
||||
m_free( ctx );
|
||||
if( !ctx->not_allocated )
|
||||
m_free( ctx );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -748,10 +760,12 @@ get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len)
|
|||
if( fprint_len == 20 || fprint_len == 16 ) {
|
||||
struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len;
|
||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
||||
rc = lookup_pk( &ctx, pk, NULL );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
else
|
||||
rc = G10ERR_GENERAL; /* Oops */
|
||||
|
@ -772,10 +786,12 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
|
|||
if( fprint_len == 20 || fprint_len == 16 ) {
|
||||
struct getkey_ctx_s ctx;
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = fprint_len;
|
||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
||||
rc = lookup_pk( &ctx, pk, ret_keyblock );
|
||||
get_pubkey_end( &ctx );
|
||||
}
|
||||
else
|
||||
rc = G10ERR_GENERAL; /* Oops */
|
||||
|
@ -806,10 +822,12 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect )
|
|||
struct getkey_ctx_s ctx;
|
||||
|
||||
memset( &ctx, 0, sizeof ctx );
|
||||
ctx.not_allocated = 1;
|
||||
ctx.primary = 1;
|
||||
ctx.nitems = 1;
|
||||
ctx.items[0].mode = 15;
|
||||
rc = lookup_sk( &ctx, sk, NULL );
|
||||
get_seckey_end( &ctx );
|
||||
}
|
||||
else {
|
||||
add_to_strlist( &namelist, name );
|
||||
|
@ -868,7 +886,8 @@ get_seckey_end( GETKEY_CTX ctx )
|
|||
enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */
|
||||
for(n=0; n < ctx->nitems; n++ )
|
||||
m_free( ctx->items[n].namebuf );
|
||||
m_free( ctx );
|
||||
if( !ctx->not_allocated )
|
||||
m_free( ctx );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1600,7 +1619,7 @@ lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
|
|||
k = find_first( ctx->keyblock, pk );
|
||||
else if( item->mode == 16 || item->mode == 20 )
|
||||
k = find_by_fpr( ctx->keyblock, pk,
|
||||
item->name, item->mode );
|
||||
item->fprint, item->mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
|
@ -1687,7 +1706,7 @@ lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
|
|||
k = find_first_sk( ctx->keyblock, sk );
|
||||
else if( item->mode == 16 || item->mode == 20 )
|
||||
k = find_by_fpr_sk( ctx->keyblock, sk,
|
||||
item->name, item->mode );
|
||||
item->fprint, item->mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
|
|
|
@ -83,15 +83,13 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
|
|||
|
||||
keygen_add_key_expire( sig, opaque );
|
||||
|
||||
buf[0] = CIPHER_ALGO_BLOWFISH;
|
||||
buf[0] = CIPHER_ALGO_TWOFISH;
|
||||
buf[1] = CIPHER_ALGO_CAST5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_SYM, buf, 2 );
|
||||
|
||||
buf[0] = DIGEST_ALGO_RMD160;
|
||||
buf[1] = DIGEST_ALGO_SHA1;
|
||||
buf[2] = DIGEST_ALGO_TIGER;
|
||||
buf[3] = DIGEST_ALGO_MD5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 4 );
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 2 );
|
||||
|
||||
buf[0] = 2;
|
||||
buf[1] = 1;
|
||||
|
|
|
@ -169,6 +169,7 @@ list_keyblock( KBNODE keyblock, int secret )
|
|||
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error("Oops; key lost!\n");
|
||||
dump_kbnode( keyblock );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,11 @@ proc_plaintext( CTX c, PACKET *pkt )
|
|||
free_md_filter_context( &c->mfx );
|
||||
c->mfx.md = md_open( 0, 0);
|
||||
/* fixme: we may need to push the textfilter if we have sigclass 1
|
||||
* and no armoring - Not yet tested */
|
||||
* and no armoring - Not yet tested
|
||||
* Hmmm, why don't we need it at all if we have sigclass 1
|
||||
* Should we assume that plaintext in mode 't' has always sigclass 1??
|
||||
* See: Russ Allbery's mail 1999-02-09
|
||||
*/
|
||||
any = clearsig = 0;
|
||||
for(n=c->list; n; n = n->next ) {
|
||||
if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
|
|
|
@ -47,6 +47,7 @@ struct {
|
|||
int def_compress_algo;
|
||||
const char *def_secret_key;
|
||||
int no_comment;
|
||||
int no_version;
|
||||
int marginals_needed;
|
||||
int completes_needed;
|
||||
int max_cert_depth;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "trustdb.h"
|
||||
#include "cipher.h"
|
||||
#include "status.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static int get_it( PKT_pubkey_enc *k,
|
||||
|
@ -179,9 +180,17 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
|||
else if( !pk->local_id && query_trust_record(pk) )
|
||||
log_error("can't check algorithm against preferences\n");
|
||||
else if( dek->algo != CIPHER_ALGO_3DES
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) )
|
||||
log_info(_("NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
&& !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) {
|
||||
/* Don't print a note while we are not on verbose mode,
|
||||
* the cipher is blowfish and the preferences have twofish
|
||||
* listed */
|
||||
if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
|
||||
|| !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM,
|
||||
CIPHER_ALGO_TWOFISH ) )
|
||||
log_info(_(
|
||||
"NOTE: cipher algorithm %d not found in preferences\n"),
|
||||
dek->algo );
|
||||
}
|
||||
free_public_key( pk );
|
||||
rc = 0;
|
||||
}
|
||||
|
|
|
@ -72,12 +72,13 @@ struct resource_table_struct {
|
|||
GDBM_FILE dbf;
|
||||
#endif
|
||||
enum resource_type rt;
|
||||
DOTLOCK lockhd;
|
||||
int is_locked;
|
||||
};
|
||||
typedef struct resource_table_struct RESTBL;
|
||||
|
||||
#define MAX_RESOURCES 10
|
||||
static RESTBL resource_table[MAX_RESOURCES];
|
||||
static const char *keyring_lock;
|
||||
|
||||
static int search( PACKET *pkt, KBPOS *kbpos, int secret );
|
||||
|
||||
|
@ -117,15 +118,40 @@ fatal_gdbm_error( const char *string )
|
|||
|
||||
#endif /* HAVE_LIBGDBM */
|
||||
|
||||
|
||||
/****************
|
||||
* Hmmm, how to avoid deadlock? They should not happen if everyone
|
||||
* locks the key resources in the same order; but who knows.
|
||||
* A solution is to use only one lock file in the gnupg homedir but
|
||||
* what will happen with key resources which normally don't belong
|
||||
* to the gpg homedir?
|
||||
*/
|
||||
static void
|
||||
cleanup( void )
|
||||
lock_rentry( RESTBL *rentry )
|
||||
{
|
||||
if( keyring_lock ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
if( !rentry->lockhd ) {
|
||||
rentry->lockhd = create_dotlock( rentry->fname );
|
||||
if( !rentry->lockhd )
|
||||
log_fatal("can't allocate lock for `%s'\n", rentry->fname );
|
||||
rentry->is_locked = 0;
|
||||
}
|
||||
if( !rentry->is_locked ) {
|
||||
if( make_dotlock( rentry->lockhd, -1 ) )
|
||||
log_fatal("can't lock `%s'\n", rentry->fname );
|
||||
rentry->is_locked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unlock_rentry( RESTBL *rentry )
|
||||
{
|
||||
if( opt.lock_once )
|
||||
return;
|
||||
if( !release_dotlock( rentry->lockhd ) )
|
||||
rentry->is_locked = 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
****************** public functions ****************************
|
||||
****************************************************************/
|
||||
|
@ -162,7 +188,6 @@ enum_keyblock_resources( int *sequence, int secret )
|
|||
int
|
||||
add_keyblock_resource( const char *url, int force, int secret )
|
||||
{
|
||||
static int initialized = 0;
|
||||
static int any_secret, any_public;
|
||||
const char *resname = url;
|
||||
IOBUF iobuf = NULL;
|
||||
|
@ -171,10 +196,6 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
int rc = 0;
|
||||
enum resource_type rt = rt_UNKNOWN;
|
||||
|
||||
if( !initialized ) {
|
||||
initialized = 1;
|
||||
atexit( cleanup );
|
||||
}
|
||||
|
||||
/* Do we have an URL?
|
||||
* gnupg-gdbm:filename := this is a GDBM resource
|
||||
|
@ -190,7 +211,7 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
rt = rt_GDBM;
|
||||
resname += 11;
|
||||
}
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DRIVE_LETTERS
|
||||
else if( strchr( resname, ':' ) ) {
|
||||
log_error("%s: invalid URL\n", url );
|
||||
rc = G10ERR_GENERAL;
|
||||
|
@ -264,7 +285,7 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
if( access(filename, F_OK) ) {
|
||||
if( strlen(filename) >= 7
|
||||
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
|
||||
#if __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if( mkdir(filename) )
|
||||
#else
|
||||
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
|
||||
|
@ -298,10 +319,10 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
else
|
||||
log_info(_("%s: keyring created\n"), filename );
|
||||
}
|
||||
#if __MINGW32__ || 1
|
||||
/* must close it again */
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
iobuf_close( iobuf );
|
||||
iobuf = NULL;
|
||||
/* must close it again */
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
@ -1039,7 +1060,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
|||
kbpos->rt = rt_RING;
|
||||
kbpos->valid = 0;
|
||||
|
||||
#if __MINGW32__ || 1
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
assert(!iobuf);
|
||||
iobuf = iobuf_open( fname );
|
||||
if( !iobuf ) {
|
||||
|
@ -1084,7 +1105,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
|||
leave:
|
||||
free_packet(&pkt);
|
||||
set_packet_list_mode(save_mode);
|
||||
#if __MINGW32__ || 1
|
||||
#if HAVE_DOSISH_SYSTEM || 1
|
||||
iobuf_close(iobuf);
|
||||
#endif
|
||||
return rc;
|
||||
|
@ -1276,10 +1297,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
if( kbpos->fp )
|
||||
BUG(); /* not allowed with such a handle */
|
||||
|
||||
if( !keyring_lock );
|
||||
keyring_lock = make_dotlock( rentry->fname, -1 );
|
||||
if( !keyring_lock )
|
||||
log_fatal("can't lock `%s'\n", rentry->fname );
|
||||
lock_rentry( rentry );
|
||||
|
||||
/* open the source file */
|
||||
fp = iobuf_open( rentry->fname );
|
||||
|
@ -1290,10 +1308,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
newfp = iobuf_create( rentry->fname );
|
||||
if( !newfp ) {
|
||||
log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno));
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
else
|
||||
|
@ -1305,28 +1320,19 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
iobuf_cancel(newfp);
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
}
|
||||
if( iobuf_close(newfp) ) {
|
||||
log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_CLOSE_FILE;
|
||||
}
|
||||
if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
|
||||
log_error("%s: chmod failed: %s\n",
|
||||
rentry->fname, strerror(errno) );
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1338,7 +1344,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
}
|
||||
|
||||
/* create the new file */
|
||||
#ifdef __MINGW32__
|
||||
#ifdef USE_ONLY_8DOT3
|
||||
/* Here is another Windoze bug?:
|
||||
* you cant rename("pubring.gpg.tmp", "pubring.gpg");
|
||||
* but rename("pubring.gpg.tmp", "pubring.aaa");
|
||||
|
@ -1451,7 +1457,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
goto leave;
|
||||
}
|
||||
/* if the new file is a secring, restrict the permissions */
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
if( rentry->secret ) {
|
||||
if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) {
|
||||
log_error("%s: chmod failed: %s\n",
|
||||
|
@ -1464,7 +1470,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
|
||||
/* rename and make backup file */
|
||||
if( !rentry->secret ) { /* but not for secret keyrings */
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
remove( bakfname );
|
||||
#endif
|
||||
if( rename( rentry->fname, bakfname ) ) {
|
||||
|
@ -1474,7 +1480,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
goto leave;
|
||||
}
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
remove( rentry->fname );
|
||||
#endif
|
||||
if( rename( tmpfname, rentry->fname ) ) {
|
||||
|
@ -1492,10 +1498,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
}
|
||||
|
||||
leave:
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( keyring_lock );
|
||||
keyring_lock = NULL;
|
||||
}
|
||||
unlock_rentry( rentry );
|
||||
m_free(bakfname);
|
||||
m_free(tmpfname);
|
||||
return rc;
|
||||
|
|
12
g10/signal.c
12
g10/signal.c
|
@ -70,7 +70,7 @@ got_usr_signal( int sig )
|
|||
caught_sigusr1 = 1;
|
||||
}
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
static void
|
||||
do_sigaction( int sig, struct sigaction *nact )
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ do_sigaction( int sig, struct sigaction *nact )
|
|||
void
|
||||
init_signals()
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
struct sigaction nact;
|
||||
|
||||
nact.sa_handler = got_fatal_signal;
|
||||
|
@ -100,7 +100,7 @@ init_signals()
|
|||
nact.sa_handler = got_usr_signal;
|
||||
sigaction( SIGUSR1, &nact, NULL );
|
||||
nact.sa_handler = SIG_IGN;
|
||||
sigaction( SIGPIPE, &nact, NULL );
|
||||
sigaction( SIGPIPE, &nact, NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ init_signals()
|
|||
void
|
||||
pause_on_sigusr( int which )
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
sigset_t mask, oldmask;
|
||||
|
||||
assert( which == 1 );
|
||||
|
@ -127,7 +127,7 @@ pause_on_sigusr( int which )
|
|||
static void
|
||||
do_block( int block )
|
||||
{
|
||||
#ifndef __MINGW32__
|
||||
#ifndef HAVE_DOSISH_SYSTEM
|
||||
static int is_blocked;
|
||||
static sigset_t oldmask;
|
||||
|
||||
|
@ -146,7 +146,7 @@ do_block( int block )
|
|||
sigprocmask( SIG_SETMASK, &oldmask, NULL );
|
||||
is_blocked = 0;
|
||||
}
|
||||
#endif /*__MINGW32__*/
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
}
|
||||
|
||||
|
||||
|
|
78
g10/tdbio.c
78
g10/tdbio.c
|
@ -77,7 +77,8 @@ struct cmp_sdir_struct {
|
|||
|
||||
|
||||
static char *db_name;
|
||||
static const char *lockname;
|
||||
static DOTLOCK lockhandle;
|
||||
static int is_locked;
|
||||
static int db_fd = -1;
|
||||
static int in_transaction;
|
||||
|
||||
|
@ -236,10 +237,12 @@ put_record_into_cache( ulong recno, const char *data )
|
|||
int n = dirty_count / 5; /* discard some dirty entries */
|
||||
if( !n )
|
||||
n = 1;
|
||||
if( !lockname )
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
}
|
||||
for( unused = NULL, r = cache_list; r; r = r->next ) {
|
||||
if( r->flags.used && r->flags.dirty ) {
|
||||
int rc = write_cache_item( r );
|
||||
|
@ -254,8 +257,8 @@ put_record_into_cache( ulong recno, const char *data )
|
|||
}
|
||||
}
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
assert( unused );
|
||||
r = unused;
|
||||
|
@ -287,17 +290,20 @@ tdbio_sync()
|
|||
CACHE_CTRL r;
|
||||
int did_lock = 0;
|
||||
|
||||
if( db_fd == -1 )
|
||||
open_db();
|
||||
if( in_transaction )
|
||||
log_bug("tdbio: syncing while in transaction\n");
|
||||
|
||||
if( !cache_is_dirty )
|
||||
return 0;
|
||||
|
||||
if( !lockname ) {
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
did_lock = 1;
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
}
|
||||
for( r = cache_list; r; r = r->next ) {
|
||||
if( r->flags.used && r->flags.dirty ) {
|
||||
|
@ -308,8 +314,8 @@ tdbio_sync()
|
|||
}
|
||||
cache_is_dirty = 0;
|
||||
if( did_lock && !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -344,17 +350,19 @@ tdbio_end_transaction()
|
|||
|
||||
if( !in_transaction )
|
||||
log_bug("tdbio: no active transaction\n");
|
||||
if( !lockname )
|
||||
lockname = make_dotlock( db_name, -1 );
|
||||
if( !lockname )
|
||||
log_fatal("can't get a lock - giving up\n");
|
||||
if( !is_locked ) {
|
||||
if( make_dotlock( lockhandle, -1 ) )
|
||||
log_fatal("can't acquire lock - giving up\n");
|
||||
else
|
||||
is_locked = 1;
|
||||
}
|
||||
block_all_signals();
|
||||
in_transaction = 0;
|
||||
rc = tdbio_sync();
|
||||
unblock_all_signals();
|
||||
if( !opt.lock_once ) {
|
||||
release_dotlock( lockname );
|
||||
lockname=NULL;
|
||||
if( !release_dotlock( lockhandle ) )
|
||||
is_locked = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -392,9 +400,9 @@ tdbio_cancel_transaction()
|
|||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
if( lockname ) {
|
||||
release_dotlock(lockname);
|
||||
lockname = NULL;
|
||||
if( is_locked ) {
|
||||
if( !release_dotlock(lockhandle) )
|
||||
is_locked = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +436,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
if( access( fname, F_OK ) ) {
|
||||
if( strlen(fname) >= 7
|
||||
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
|
||||
#if __MINGW32__
|
||||
#if HAVE_DOSISH_SYSTEM
|
||||
if( mkdir( fname ) )
|
||||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
|
@ -450,7 +458,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
fclose(fp);
|
||||
m_free(db_name);
|
||||
db_name = fname;
|
||||
#ifdef __MINGW32__
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
db_fd = open( db_name, O_RDWR | O_BINARY );
|
||||
#else
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
|
@ -501,7 +509,10 @@ open_db()
|
|||
TRUSTREC rec;
|
||||
assert( db_fd == -1 );
|
||||
|
||||
#ifdef __MINGW32__
|
||||
lockhandle = create_dotlock( db_name );
|
||||
if( !lockhandle )
|
||||
log_fatal( _("%s: can't create lock\n"), db_name );
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
db_fd = open( db_name, O_RDWR | O_BINARY );
|
||||
#else
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
|
@ -970,6 +981,8 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
|||
rec->r.uid.prefrec,
|
||||
rec->r.uid.siglist,
|
||||
rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
|
||||
if( rec->r.uid.uidflags & UIDF_VALVALID )
|
||||
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 );
|
||||
|
@ -1155,7 +1168,18 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
rec->r.uid.prefrec = buftoulong(p); p += 4;
|
||||
rec->r.uid.siglist = buftoulong(p); p += 4;
|
||||
rec->r.uid.uidflags = *p++;
|
||||
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 */
|
||||
|
@ -1278,7 +1302,7 @@ tdbio_write_record( TRUSTREC *rec )
|
|||
ulongtobuf(p, rec->r.uid.prefrec); p += 4;
|
||||
ulongtobuf(p, rec->r.uid.siglist); p += 4;
|
||||
*p++ = rec->r.uid.uidflags;
|
||||
p++;
|
||||
*p++ = rec->r.uid.validity;
|
||||
memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
|
||||
break;
|
||||
|
||||
|
|
10
g10/tdbio.h
10
g10/tdbio.h
|
@ -59,9 +59,10 @@
|
|||
#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 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 UIDF_VALVALID 16 /* the validity field is valid */
|
||||
|
||||
#define SIGF_CHECKED 1 /* signature has been checked - bits 0..6 are valid */
|
||||
#define SIGF_VALID 2 /* the signature is valid */
|
||||
|
@ -98,7 +99,7 @@ struct trust_record {
|
|||
ulong cacherec; /* the cache record */
|
||||
byte ownertrust;
|
||||
byte dirflags;
|
||||
byte validity; /* calculated trustlevel */
|
||||
byte validity; /* calculated trustlevel over all uids */
|
||||
} dir;
|
||||
struct { /* primary public key record */
|
||||
ulong lid;
|
||||
|
@ -114,6 +115,7 @@ struct trust_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 */
|
||||
|
|
253
g10/trustdb.c
253
g10/trustdb.c
|
@ -104,6 +104,8 @@ static void release_lid_table( LOCAL_ID_TABLE tbl );
|
|||
static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
|
||||
static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
|
||||
|
||||
|
||||
|
||||
static void print_user_id( const char *text, u32 *keyid );
|
||||
static void sort_tsl_list( TRUST_SEG_LIST *trust_seg_list );
|
||||
static int list_sigs( ulong pubkey_id );
|
||||
|
@ -839,42 +841,13 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
ulong rn, uidrn;
|
||||
int marginal=0;
|
||||
int fully=0;
|
||||
LOCAL_ID_TABLE sigs_seen = NULL;
|
||||
/*LOCAL_ID_TABLE sigs_seen = NULL;*/
|
||||
|
||||
if( depth >= max_depth ) /* max cert_depth reached */
|
||||
return TRUST_UNDEFINED;
|
||||
|
||||
stack[depth].lid = drec->r.dir.lid;
|
||||
stack[depth].otrust = drec->r.dir.ownertrust;
|
||||
stack[depth].trust = 0;
|
||||
{ int i;
|
||||
|
||||
for(i=0; i < depth; i++ )
|
||||
if( stack[i].lid == drec->r.dir.lid )
|
||||
return TRUST_UNDEFINED; /* closed (we already visited this lid) */
|
||||
}
|
||||
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
|
||||
/* we are at the end of a path */
|
||||
TRUST_SEG_LIST tsl;
|
||||
int i;
|
||||
|
||||
stack[depth].trust = TRUST_ULTIMATE;
|
||||
stack[depth].otrust = TRUST_ULTIMATE;
|
||||
if( trust_seg_head ) {
|
||||
/* we can now put copy our current stack to the trust_seg_list */
|
||||
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
|
||||
for(i=0; i <= depth; i++ )
|
||||
tsl->path[i] = stack[i];
|
||||
tsl->pathlen = i;
|
||||
tsl->next = *trust_seg_head;
|
||||
*trust_seg_head = tsl;
|
||||
}
|
||||
return TRUST_ULTIMATE;
|
||||
}
|
||||
|
||||
/* loop over all user-ids */
|
||||
if( !all )
|
||||
sigs_seen = new_lid_table();
|
||||
/*if( !all ) sigs_seen = new_lid_table();*/
|
||||
for( rn = drec->r.dir.uidlist; rn; rn = uidrn ) {
|
||||
TRUSTREC rec; /* used for uids and sigs */
|
||||
ulong sigrn;
|
||||
|
@ -888,7 +861,36 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
if( (rec.r.uid.uidflags & UIDF_REVOKED) )
|
||||
continue; /* user id has been revoked */
|
||||
|
||||
/* loop over all signature records */
|
||||
stack[depth].lid = drec->r.dir.lid;
|
||||
stack[depth].otrust = drec->r.dir.ownertrust;
|
||||
stack[depth].trust = 0;
|
||||
{ int i;
|
||||
|
||||
for(i=0; i < depth; i++ )
|
||||
if( stack[i].lid == drec->r.dir.lid )
|
||||
return TRUST_UNDEFINED; /* closed (we already visited this lid) */
|
||||
}
|
||||
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
|
||||
/* we are at the end of a path */
|
||||
TRUST_SEG_LIST tsl;
|
||||
int i;
|
||||
|
||||
stack[depth].trust = TRUST_ULTIMATE;
|
||||
stack[depth].otrust = TRUST_ULTIMATE;
|
||||
if( trust_seg_head ) {
|
||||
/* we can now put copy our current stack to the trust_seg_list */
|
||||
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
|
||||
for(i=0; i <= depth; i++ )
|
||||
tsl->path[i] = stack[i];
|
||||
tsl->pathlen = i;
|
||||
tsl->next = *trust_seg_head;
|
||||
*trust_seg_head = tsl;
|
||||
}
|
||||
return TRUST_ULTIMATE;
|
||||
}
|
||||
|
||||
|
||||
/* loop over all signature records of this user id */
|
||||
for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
|
||||
int i;
|
||||
|
||||
|
@ -917,11 +919,11 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
}
|
||||
|
||||
/* visit every signer only once (a signer may have
|
||||
* signed more than one user ID) */
|
||||
if( sigs_seen && ins_lid_table_item( sigs_seen,
|
||||
rec.r.sig.sig[i].lid, 0) )
|
||||
continue; /* we already have this one */
|
||||
|
||||
* signed more than one user ID)
|
||||
* if( sigs_seen && ins_lid_table_item( sigs_seen,
|
||||
* rec.r.sig.sig[i].lid, 0) )
|
||||
* continue; we already have this one
|
||||
*/
|
||||
read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
|
||||
if( tmp.rectype != RECTYPE_DIR ) {
|
||||
if( tmp.rectype != RECTYPE_SDIR )
|
||||
|
@ -945,8 +947,7 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
/* we have signed this key and only in this special case
|
||||
* we assume that this one is fully trusted */
|
||||
if( !all ) {
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
|
||||
return (stack[depth].trust = TRUST_FULLY);
|
||||
}
|
||||
}
|
||||
|
@ -962,16 +963,14 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
if( fully >= opt.completes_needed
|
||||
|| marginal >= opt.marginals_needed ) {
|
||||
if( !all ) {
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
|
||||
return (stack[depth].trust = TRUST_FULLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( sigs_seen )
|
||||
release_lid_table( sigs_seen );
|
||||
/*if( sigs_seen ) release_lid_table( sigs_seen ); */
|
||||
if( all && ( fully >= opt.completes_needed
|
||||
|| marginal >= opt.marginals_needed ) ) {
|
||||
return (stack[depth].trust = TRUST_FULLY );
|
||||
|
@ -983,6 +982,145 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
|
|||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
ulong lid;
|
||||
ulong uid;
|
||||
} CERT_ITEM;
|
||||
|
||||
/* structure to hold certification chains. Item[nitems-1] is the
|
||||
* ultimateley trusted key, item[0] is the key which
|
||||
* is introduced, indices [1,(nitems-2)] are all introducers.
|
||||
*/
|
||||
typedef struct cert_chain *CERT_CHAIN;
|
||||
struct cert_chain {
|
||||
CERT_CHAIN next;
|
||||
int dups;
|
||||
int nitems;
|
||||
CERT_ITEM items[1];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Copy all items to the set SET_HEAD in a way that the requirements
|
||||
* of a CERT_CHAIN are met.
|
||||
*/
|
||||
static void
|
||||
add_cert_items_to_set( CERT_CHAIN *set_head, CERT_ITEM *items, int nitems )
|
||||
{
|
||||
CERT_CHAIN ac;
|
||||
int i;
|
||||
|
||||
ac = m_alloc_clear( sizeof *ac + (nitems-1)*sizeof(CERT_ITEM) );
|
||||
ac->nitems = nitems;
|
||||
for(i=0; i < nitems; i++ )
|
||||
ac->items[i] = items[i];
|
||||
ac->next = *set_head;
|
||||
*set_head = ac;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Find all certification paths of a given LID.
|
||||
* Limit the search to MAX_DEPTH. stack is a helper variable which
|
||||
* should have been allocated with size max_depth, stack[0] should
|
||||
* be setup to the key we are investigating, so the minimal depth
|
||||
* we should ever see in this function is 1.
|
||||
* Returns: -1 max_depth reached
|
||||
* 0 no paths found
|
||||
* 1 ultimately trusted key found
|
||||
* certchain_set must be a valid set or point to NULL; this function
|
||||
* may modifiy it.
|
||||
*/
|
||||
static int
|
||||
find_cert_chain( ulong lid, int depth, int max_depth,
|
||||
CERT_ITEM *stack, CERT_CHAIN *cert_chain_set )
|
||||
{
|
||||
TRUSTREC dirrec;
|
||||
TRUSTREC uidrec;
|
||||
ulong uidrno;
|
||||
|
||||
if( depth >= max_depth )
|
||||
return -1;
|
||||
|
||||
stack[depth].lid = lid;
|
||||
stack[depth].uid = 0;
|
||||
|
||||
if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
|
||||
/* this is an ultimately trusted key;
|
||||
* which means that we have found the end of the chain:
|
||||
* copy the chain to the set */
|
||||
add_cert_items_to_set( cert_chain_set, stack, depth+1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
read_record( lid, &dirrec, 0 );
|
||||
if( dirrec.rectype != RECTYPE_DIR ) {
|
||||
if( dirrec.rectype != RECTYPE_SDIR )
|
||||
log_debug("lid %lu, has rectype %d"
|
||||
" - skipped\n", lid, dirrec.rectype );
|
||||
return 0;
|
||||
}
|
||||
/* Performance hint: add stuff to ignore this one when the
|
||||
* assigned validity of the key is bad */
|
||||
|
||||
/* loop over all user ids */
|
||||
for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
|
||||
TRUSTREC sigrec;
|
||||
ulong sigrno;
|
||||
|
||||
stack[depth].uid = uidrno;
|
||||
read_record( uidrno, &uidrec, RECTYPE_UID );
|
||||
|
||||
if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
|
||||
continue; /* user id has not been checked */
|
||||
if( !(uidrec.r.uid.uidflags & UIDF_VALID) )
|
||||
continue; /* user id is not valid */
|
||||
if( (uidrec.r.uid.uidflags & UIDF_REVOKED) )
|
||||
continue; /* user id has been revoked */
|
||||
|
||||
/* loop over all signature records */
|
||||
for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
|
||||
int i, j;
|
||||
|
||||
read_record( sigrno, &sigrec, RECTYPE_SIG );
|
||||
|
||||
for(i=0; i < SIGS_PER_RECORD; i++ ) {
|
||||
if( !sigrec.r.sig.sig[i].lid )
|
||||
continue; /* skip deleted sigs */
|
||||
if( !(sigrec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||
continue; /* skip unchecked signatures */
|
||||
if( !(sigrec.r.sig.sig[i].flag & SIGF_VALID) )
|
||||
continue; /* skip invalid signatures */
|
||||
if( (sigrec.r.sig.sig[i].flag & SIGF_EXPIRED) )
|
||||
continue; /* skip expired signatures */
|
||||
if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
|
||||
continue; /* skip revoked signatures */
|
||||
for(j=0; j < depth; j++ ) {
|
||||
if( stack[j].lid == sigrec.r.sig.sig[i].lid )
|
||||
break;
|
||||
}
|
||||
if( j < depth )
|
||||
continue; /* avoid cycles as soon as possible */
|
||||
|
||||
if( find_cert_chain( sigrec.r.sig.sig[i].lid,
|
||||
depth+1, max_depth,
|
||||
stack, cert_chain_set ) > 0 ) {
|
||||
/* ultimately trusted key found:
|
||||
* no need to check more signatures of this uid */
|
||||
sigrec.r.sig.next = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end loop over sig recs */
|
||||
} /* end loop over user ids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Given the directory record of a key, check whether we can
|
||||
* find a path to an ultimately trusted key. We do this by
|
||||
|
@ -1337,6 +1475,7 @@ void
|
|||
list_trust_path( const char *username )
|
||||
{
|
||||
int rc;
|
||||
ulong lid;
|
||||
TRUSTREC rec;
|
||||
TRUST_INFO *tmppath;
|
||||
TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
|
||||
|
@ -1357,8 +1496,10 @@ list_trust_path( const char *username )
|
|||
assert( pk->local_id );
|
||||
}
|
||||
}
|
||||
lid = pk->local_id;
|
||||
free_public_key( pk );
|
||||
|
||||
#if 0
|
||||
/* collect the paths */
|
||||
tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
|
||||
trust_seg_list = NULL;
|
||||
|
@ -1378,6 +1519,26 @@ list_trust_path( const char *username )
|
|||
m_free( tsl );
|
||||
}
|
||||
trust_seg_list = NULL;
|
||||
#else /* test code */
|
||||
{
|
||||
CERT_ITEM *stack;
|
||||
CERT_CHAIN chains, r;
|
||||
int i;
|
||||
|
||||
chains = NULL;
|
||||
stack = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *stack );
|
||||
find_cert_chain( lid, 0, opt.max_cert_depth, stack, &chains);
|
||||
m_free( stack );
|
||||
/* dump chains */
|
||||
for(r=chains; r ; r = r->next ) {
|
||||
printf("chain:" );
|
||||
for(i=0; i < r->nitems; i++ )
|
||||
printf(" %4lu/%-4lu", r->items[i].lid, r->items[i].uid );
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2719,15 +2880,17 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
|||
continue; /* skip deleted sigs */
|
||||
}
|
||||
if( rec.r.sig.sig[i].lid == pk_lid ) {
|
||||
#if 0 /* must take uid into account */
|
||||
if( found_sig ) {
|
||||
log_info( "sig %08lX.%lu/%02X%02X/%08lX: %s\n",
|
||||
(ulong)keyid[1], lid, uidhash[18],
|
||||
uidhash[19], (ulong)sig->keyid[1],
|
||||
_("Duplicated certificate - deleted") );
|
||||
_("duplicated certificate - deleted") );
|
||||
rec.r.sig.sig[i].lid = 0;
|
||||
rec.dirty = 1;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
found_sig = 1;
|
||||
}
|
||||
if( !recheck && !revoke && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
|
||||
|
@ -2811,7 +2974,7 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
|
|||
}
|
||||
}
|
||||
|
||||
if( found_sig )
|
||||
if( found_sig ) /* fixme: uid stuff */
|
||||
return;
|
||||
|
||||
/* at this point, we have verified, that the signature is not in
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue