mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Epxerimenta support for GDBM keyings.
This commit is contained in:
parent
6e16296864
commit
e309a875cb
36 changed files with 1049 additions and 558 deletions
|
@ -1,3 +1,27 @@
|
|||
Wed Oct 21 18:19:36 1998 Michael Roth <mroth@nessie.de>
|
||||
|
||||
* ringedit.c (add_keyblock_resource): Directory is now created.
|
||||
* tdbio.c (tdbio_set_dbname): New info message.
|
||||
|
||||
Wed Oct 21 11:52:04 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* trustdb.c (update_trustdb): released keyblock in loop.
|
||||
|
||||
* keylist.c (list_block): New.
|
||||
(list_all): Changed to use list_block.
|
||||
|
||||
* trustdb.c: Completed support for GDBM
|
||||
|
||||
* sign.c (only_old_style): Changed the way force_v3 is handled
|
||||
(sign_file): Ditto.
|
||||
(clearsign_file): Ditto.
|
||||
|
||||
* keygen.c (has_invalid_email_chars): Splitted into mailbox and
|
||||
host part.
|
||||
|
||||
* keylist.c (list_one): Add a merge_keys_and_selfsig.
|
||||
* mainproc.c (proc_tree): Ditto.
|
||||
|
||||
Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* sign.c (only_old_style): Add option force_v3_sigs
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
EXTRA_DIST = OPTIONS pubring.asc
|
||||
OMIT_DEPENDENCIES = zlib.h zconf.h
|
||||
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
|
||||
|
@ -76,7 +76,7 @@ gpgm_SOURCES = dearmor.c \
|
|||
# $(common_source)
|
||||
|
||||
|
||||
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
|
||||
LDADD = $(needed_libs) @ZLIBS@ @INTLLIBS@
|
||||
|
||||
gpgm_LDADD = g10maint.o $(LDADD)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* delkey.c - delte keys
|
||||
/* delkey.c - delete keys
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
|
|
400
g10/getkey.c
400
g10/getkey.c
|
@ -683,6 +683,182 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
|||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name,
|
||||
int mode, byte *namehash, int *use_namehash )
|
||||
{
|
||||
KBNODE k, kk;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_USER_ID
|
||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len, name, mode)) {
|
||||
/* we found a matching name, look for the key */
|
||||
for(kk=keyblock; kk; kk = kk->next ) {
|
||||
if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== kk->pkt->pkt.public_key->pubkey_algo)
|
||||
&& ( !pk->pubkey_usage
|
||||
|| !check_pubkey_algo2(
|
||||
kk->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ))
|
||||
)
|
||||
break;
|
||||
}
|
||||
if( kk ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
*use_namehash = 1;
|
||||
return kk;
|
||||
}
|
||||
else if( is_RSA(pk->pubkey_algo) )
|
||||
log_error("RSA key cannot be used in this version\n");
|
||||
else
|
||||
log_error("No key for userid\n");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_keyid( KBNODE keyblock, PKT_public_key *pk, u32 *keyid, int mode )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
if( DBG_CACHE )
|
||||
log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
|
||||
(ulong)keyid[0], (ulong)keyid[1], pk->pubkey_algo, mode );
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
if( DBG_CACHE )
|
||||
log_debug(" aki=%08lx%08lx algo=%d\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo );
|
||||
|
||||
if( aki[1] == keyid[1]
|
||||
&& ( mode == 10 || aki[0] == keyid[0] )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ){
|
||||
KBNODE kk;
|
||||
/* cache the userid */
|
||||
for(kk=keyblock; kk; kk = kk->next )
|
||||
if( kk->pkt->pkttype == PKT_USER_ID )
|
||||
break;
|
||||
if( kk )
|
||||
cache_user_id( kk->pkt->pkt.user_id, aki );
|
||||
else
|
||||
log_error("No userid for key\n");
|
||||
return k; /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_first( KBNODE keyblock, PKT_public_key *pk )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
{
|
||||
if( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo )
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_fpr( KBNODE keyblock, PKT_public_key *pk, const char *name, int mode )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
|
||||
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
|
||||
|
||||
if( DBG_CACHE ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
log_debug(" aki=%08lx%08lx algo=%d mode=%d an=%u\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo, mode, an );
|
||||
}
|
||||
|
||||
if( an == mode
|
||||
&& !memcmp( afp, name, an)
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo) )
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
int use_namehash, int primary )
|
||||
{
|
||||
assert( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||
if( primary && !pk->pubkey_usage ) {
|
||||
copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, keyblock );
|
||||
}
|
||||
else {
|
||||
if( primary && pk->pubkey_usage
|
||||
&& check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
|
||||
/* if the usage is not correct, try to use a subkey */
|
||||
KBNODE save_k = k;
|
||||
|
||||
for( ; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
&& !check_pubkey_algo2(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
break;
|
||||
}
|
||||
if( !k )
|
||||
k = save_k;
|
||||
else
|
||||
log_info(_("using secondary key %08lX "
|
||||
"instead of primary key %08lX\n"),
|
||||
(ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
|
||||
(ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
|
||||
);
|
||||
}
|
||||
|
||||
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, k );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -709,175 +885,87 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
|
|||
{
|
||||
int rc;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE k;
|
||||
KBPOS kbpos;
|
||||
int oldmode = set_packet_list_mode(0);
|
||||
byte namehash[20];
|
||||
int use_namehash=0;
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else if( rc )
|
||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
/* try the quick functions */
|
||||
k = NULL;
|
||||
switch( mode ) {
|
||||
case 10:
|
||||
case 11:
|
||||
rc = locate_keyblock_by_keyid( &kbpos, keyid, mode==10, 0 );
|
||||
if( !rc )
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( !rc )
|
||||
k = find_by_keyid( keyblock, pk, keyid, mode );
|
||||
break;
|
||||
|
||||
case 16:
|
||||
case 20:
|
||||
rc = locate_keyblock_by_fpr( &kbpos, name, mode, 0 );
|
||||
if( !rc )
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( !rc )
|
||||
k = find_by_fpr( keyblock, pk, name, mode );
|
||||
break;
|
||||
|
||||
default: rc = G10ERR_UNSUPPORTED;
|
||||
}
|
||||
if( !rc ) {
|
||||
if( !k ) {
|
||||
log_error("lookup: key has been located but was not found\n");
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
}
|
||||
else
|
||||
finish_lookup( keyblock, pk, k, namehash, 0, primary );
|
||||
}
|
||||
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
KBNODE k, kk;
|
||||
if( mode < 10 ) { /* name lookup */
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_USER_ID
|
||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len, name, mode)) {
|
||||
/* we found a matching name, look for the key */
|
||||
for(kk=keyblock; kk; kk = kk->next ) {
|
||||
if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== kk->pkt->pkt.public_key->pubkey_algo)
|
||||
&& ( !pk->pubkey_usage
|
||||
|| !check_pubkey_algo2(
|
||||
kk->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ))
|
||||
)
|
||||
break;
|
||||
}
|
||||
if( kk ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
use_namehash = 1;
|
||||
k = kk;
|
||||
break;
|
||||
}
|
||||
else
|
||||
log_error("No key for userid\n");
|
||||
/* if this was not possible, loop over all keyblocks
|
||||
* fixme: If one of the resources in the quick functions above
|
||||
* works, but the key was not found, we will not find it
|
||||
* in the other resources */
|
||||
if( rc == G10ERR_UNSUPPORTED ) {
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( !rc ) {
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
if( mode < 10 )
|
||||
k = find_by_name( keyblock, pk, name, mode,
|
||||
namehash, &use_namehash);
|
||||
else if( mode == 10 || mode == 11 )
|
||||
k = find_by_keyid( keyblock, pk, keyid, mode );
|
||||
else if( mode == 15 )
|
||||
k = find_first( keyblock, pk );
|
||||
else if( mode == 16 || mode == 20 )
|
||||
k = find_by_fpr( keyblock, pk, name, mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
finish_lookup( keyblock, pk, k, namehash,
|
||||
use_namehash, primary );
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* keyid or fingerprint lookup */
|
||||
if( DBG_CACHE && (mode== 10 || mode==11) ) {
|
||||
log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
|
||||
(ulong)keyid[0], (ulong)keyid[1],
|
||||
pk->pubkey_algo, mode );
|
||||
}
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
if( mode == 10 || mode == 11 ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
if( DBG_CACHE ) {
|
||||
log_debug(" aki=%08lx%08lx algo=%d\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo );
|
||||
}
|
||||
if( aki[1] == keyid[1]
|
||||
&& ( mode == 10 || aki[0] == keyid[0] )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ){
|
||||
/* cache the userid */
|
||||
for(kk=keyblock; kk; kk = kk->next )
|
||||
if( kk->pkt->pkttype == PKT_USER_ID )
|
||||
break;
|
||||
if( kk )
|
||||
cache_user_id( kk->pkt->pkt.user_id, aki );
|
||||
else
|
||||
log_error("No userid for key\n");
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
else if( mode == 15 ) { /* get the first key */
|
||||
if( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo )
|
||||
break;
|
||||
}
|
||||
else if( mode == 16 || mode == 20 ) {
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
|
||||
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
|
||||
|
||||
if( DBG_CACHE ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
log_debug(" aki=%08lx%08lx algo=%d mode=%d an=%u\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
mode, an );
|
||||
}
|
||||
if( an == mode && !memcmp( afp, name, an)
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
BUG();
|
||||
} /* end compare public keys */
|
||||
}
|
||||
}
|
||||
if( k ) { /* found */
|
||||
assert( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||
if( primary && !pk->pubkey_usage ) {
|
||||
copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, keyblock );
|
||||
}
|
||||
else {
|
||||
if( primary && pk->pubkey_usage
|
||||
&& check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
|
||||
/* if the usage is not correct, try to use a subkey */
|
||||
KBNODE save_k = k;
|
||||
|
||||
for( ; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
&& !check_pubkey_algo2(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
break;
|
||||
}
|
||||
if( !k )
|
||||
k = save_k;
|
||||
else
|
||||
log_info(_("using secondary key %08lX "
|
||||
"instead of primary key %08lX\n"),
|
||||
(ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
|
||||
(ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
|
||||
);
|
||||
}
|
||||
|
||||
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, k );
|
||||
}
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
release_kbnode( keyblock );
|
||||
keyblock = NULL;
|
||||
}
|
||||
break; /* enumeration */
|
||||
}
|
||||
release_kbnode( keyblock );
|
||||
keyblock = NULL;
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
||||
}
|
||||
if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else if( rc )
|
||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
||||
|
||||
leave:
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
if( !rc ) {
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
keyblock = NULL;
|
||||
}
|
||||
}
|
||||
else if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
|
||||
|
||||
release_kbnode( keyblock );
|
||||
set_packet_list_mode(oldmode);
|
||||
if( opt.debug & DBG_MEMSTAT_VALUE ) {
|
||||
|
|
|
@ -46,6 +46,7 @@ new_kbnode( PACKET *pkt )
|
|||
n->pkt = pkt;
|
||||
n->flag = 0;
|
||||
n->private_flag=0;
|
||||
n->recno = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ struct kbnode_struct {
|
|||
PACKET *pkt;
|
||||
int flag;
|
||||
int private_flag;
|
||||
ulong recno; /* used while updating the trustdb */
|
||||
};
|
||||
|
||||
|
||||
|
@ -69,6 +70,7 @@ struct keyblock_pos_struct {
|
|||
int secret; /* working on a secret keyring */
|
||||
#ifdef HAVE_LIBGDBM
|
||||
GDBM_FILE dbf;
|
||||
byte keybuf[21];
|
||||
#endif
|
||||
PACKET *pkt; /* ditto */
|
||||
};
|
||||
|
@ -172,6 +174,10 @@ const char *enum_keyblock_resources( int *sequence, int secret );
|
|||
int add_keyblock_resource( const char *resname, int force, int secret );
|
||||
const char *keyblock_resource_name( KBPOS *kbpos );
|
||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||
int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
|
||||
int fprlen, int secret );
|
||||
int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
|
||||
int shortkid, int secret );
|
||||
int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
|
||||
int find_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||
int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
||||
|
|
10
g10/keygen.c
10
g10/keygen.c
|
@ -541,10 +541,18 @@ ask_expiredate()
|
|||
static int
|
||||
has_invalid_email_chars( const char *s )
|
||||
{
|
||||
int at_seen=0;
|
||||
|
||||
for( ; *s; s++ ) {
|
||||
if( *s & 0x80 )
|
||||
return 1;
|
||||
if( !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.@", *s ) )
|
||||
if( *s == '@' )
|
||||
at_seen=1;
|
||||
else if( !at_seen
|
||||
&& !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.+", *s ))
|
||||
return 1;
|
||||
else if( at_seen
|
||||
&& !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.", *s ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
103
g10/keylist.c
103
g10/keylist.c
|
@ -37,6 +37,7 @@
|
|||
|
||||
static void list_all(int);
|
||||
static void list_one(const char *name, int secret);
|
||||
static void list_keyblock( KBNODE keyblock, int secret );
|
||||
static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
|
||||
|
||||
|
||||
|
@ -70,63 +71,87 @@ secret_key_list( int nnames, char **names )
|
|||
static void
|
||||
list_all( int secret )
|
||||
{
|
||||
int i, seq=0;
|
||||
const char *s;
|
||||
IOBUF a;
|
||||
KBPOS kbpos;
|
||||
KBNODE keyblock = NULL;
|
||||
int rc=0;
|
||||
int lastresno;
|
||||
|
||||
/* FIXME: this assumes a keyring resource is a plain keyring file */
|
||||
while( (s = enum_keyblock_resources( &seq, secret )) ) {
|
||||
if( !(a = iobuf_open(s)) ) {
|
||||
log_error(_("can't open %s: %s\n"), s, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if( seq > 1 )
|
||||
putchar('\n');
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
if( rc != -1 )
|
||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
lastresno = -1;
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
if( lastresno != kbpos.resno ) {
|
||||
const char *s = keyblock_resource_name( &kbpos );
|
||||
int i;
|
||||
|
||||
lastresno = kbpos.resno;
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
}
|
||||
merge_keys_and_selfsig( keyblock );
|
||||
list_keyblock( keyblock, secret );
|
||||
release_kbnode( keyblock ); keyblock = NULL;
|
||||
}
|
||||
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
||||
|
||||
leave:
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
list_one( const char *name, int secret )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
|
||||
rc = secret? find_secret_keyblock_byname( &kbpos, name )
|
||||
: find_keyblock_byname( &kbpos, name );
|
||||
if( rc ) {
|
||||
log_error("%s: user not found\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
|
||||
return;
|
||||
}
|
||||
merge_keys_and_selfsig( keyblock );
|
||||
list_keyblock( keyblock, secret );
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
list_keyblock( KBNODE keyblock, int secret )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
KBPOS kbpos;
|
||||
PKT_public_key *pk;
|
||||
PKT_secret_key *sk;
|
||||
u32 keyid[2];
|
||||
int any=0;
|
||||
int trustletter = 0;
|
||||
|
||||
/* search the userid */
|
||||
rc = secret? find_secret_keyblock_byname( &kbpos, name )
|
||||
: find_keyblock_byname( &kbpos, name );
|
||||
if( rc ) {
|
||||
log_error("%s: user not found\n", name );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* read the keyblock */
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error("Oops; key lost!\n");
|
||||
goto leave;
|
||||
return;
|
||||
}
|
||||
|
||||
if( secret ) {
|
||||
|
@ -336,12 +361,10 @@ list_one( const char *name, int secret )
|
|||
putchar(':');
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
|
||||
{
|
||||
|
|
|
@ -886,10 +886,14 @@ proc_tree( CTX c, KBNODE node )
|
|||
c->local_id = 0;
|
||||
c->trustletter = ' ';
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
merge_keys_and_selfsig( node );
|
||||
list_node( c, node );
|
||||
else if( node->pkt->pkttype == PKT_SECRET_KEY )
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
merge_keys_and_selfsig( node );
|
||||
list_node( c, node );
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
/* check all signatures */
|
||||
if( !c->have_data ) {
|
||||
|
|
551
g10/ringedit.c
551
g10/ringedit.c
|
@ -35,8 +35,6 @@
|
|||
*
|
||||
* - Delete a key block
|
||||
*
|
||||
* FIXME: Keep track of all nodes, so that a change is propagated
|
||||
* to all nodes. (or use shallow copies and ref-counting?)
|
||||
*/
|
||||
|
||||
|
||||
|
@ -59,10 +57,10 @@
|
|||
#include "mpi.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "host2net.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#undef HAVE_LIBGDBM /* <--- not ready */
|
||||
|
||||
struct resource_table_struct {
|
||||
int used;
|
||||
|
@ -88,6 +86,14 @@ static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
|
|||
static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
|
||||
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
static int do_gdbm_store( KBPOS *kbpos, KBNODE root, int update );
|
||||
static int do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos,
|
||||
const byte *fpr, int fprlen );
|
||||
static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );
|
||||
static int do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root );
|
||||
static int do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root );
|
||||
#endif
|
||||
|
||||
|
||||
static RESTBL *
|
||||
|
@ -100,6 +106,14 @@ check_pos( KBPOS *kbpos )
|
|||
return resource_table + kbpos->resno;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
static void
|
||||
fatal_gdbm_error( const char *string )
|
||||
{
|
||||
log_fatal("gdbm failed: %s\n", string);
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBGDBM */
|
||||
|
||||
/****************************************************************
|
||||
****************** public functions ****************************
|
||||
|
@ -188,9 +202,33 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
goto leave;
|
||||
}
|
||||
|
||||
/* see whether we can determine the filetype */
|
||||
if( rt == rt_UNKNOWN ) {
|
||||
FILE *fp = fopen( filename, "rb" );
|
||||
|
||||
if( fp ) {
|
||||
u32 magic;
|
||||
|
||||
if( fread( &magic, 4, 1, fp) == 1 ) {
|
||||
if( magic == 0x13579ace )
|
||||
rt = rt_GDBM;
|
||||
else if( magic == 0xce9a5713 )
|
||||
log_error("%s: endianess does not match\n", url );
|
||||
else
|
||||
rt = rt_RING;
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
else /* no file yet: create ring */
|
||||
rt = rt_RING;
|
||||
}
|
||||
|
||||
switch( rt ) {
|
||||
case rt_UNKNOWN:
|
||||
log_error("%s: unknown resource type\n", url );
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
|
||||
case rt_RING:
|
||||
iobuf = iobuf_fopen( filename, "rb" );
|
||||
if( !iobuf && !force ) {
|
||||
|
@ -199,20 +237,46 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
}
|
||||
|
||||
if( !iobuf ) {
|
||||
char *last_slash_in_filename;
|
||||
|
||||
last_slash_in_filename = strrchr(filename, '/');
|
||||
*last_slash_in_filename = 0;
|
||||
|
||||
if( access(filename, F_OK) ) {
|
||||
if( strlen(filename) >= 7
|
||||
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
|
||||
#if __MINGW32__
|
||||
if( mkdir(filename) )
|
||||
#else
|
||||
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
|
||||
#endif
|
||||
{
|
||||
log_error( _("%s: can't create directory: %s\n"),
|
||||
filename, strerror(errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
log_info( _("%s: directory created\n"), filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
*last_slash_in_filename = '/';
|
||||
|
||||
iobuf = iobuf_create( filename );
|
||||
if( !iobuf ) {
|
||||
log_error("%s: can't create: %s\n", filename, strerror(errno));
|
||||
log_error("%s: can't create keyring: %s\n", filename, strerror(errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
log_info("%s: keyring created\n", filename );
|
||||
}
|
||||
/* fixme: see whether it is really a ring or if type is unknown,
|
||||
* try to figure out of what type it is
|
||||
*/
|
||||
rt = rt_RING; /* <--- FIXME */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* must close it again */
|
||||
iobuf_close( iobuf );
|
||||
|
@ -222,6 +286,17 @@ add_keyblock_resource( const char *url, int force, int secret )
|
|||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
resource_table[i].dbf = gdbm_open( filename, 0,
|
||||
force? GDBM_WRCREAT : GDBM_WRITER,
|
||||
S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IWGRP | S_IROTH,
|
||||
fatal_gdbm_error );
|
||||
if( !resource_table[i].dbf ) {
|
||||
log_error("%s: can't open gdbm file: %s\n",
|
||||
filename, gdbm_strerror(gdbm_errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -310,14 +385,21 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
|
|||
resource_table[i].fname );
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM
|
||||
rc = do_gdbm_search( pkt, kbpos, resource_table[i].dbf,
|
||||
resource_table[i].fname );
|
||||
case rt_GDBM: {
|
||||
PKT_public_key *req_pk = pkt->pkt.public_key;
|
||||
byte fpr[20];
|
||||
size_t fprlen;
|
||||
|
||||
fingerprint_from_pk( req_pk, fpr, &fprlen );
|
||||
rc = do_gdbm_locate( resource_table[i].dbf,
|
||||
kbpos, fpr, fprlen );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
kbpos->rt = resource_table[i].rt;
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
|
@ -404,6 +486,92 @@ find_secret_keyblock_byname( KBPOS *kbpos, const char *username )
|
|||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Locate a keyblock in a database which is capable of direct access
|
||||
* Put all information into KBPOS, which can be later be to access this
|
||||
* key block.
|
||||
* This function looks into all registered keyblock sources.
|
||||
*
|
||||
* Returns: 0 if found,
|
||||
* -1 if not found
|
||||
* G10ERR_UNSUPPORTED if no resource is able to handle this
|
||||
* or another errorcode.
|
||||
*/
|
||||
int
|
||||
locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr, int fprlen, int secret )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate( rentry->dbf, kbpos, fpr, fprlen );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int shortkid, int secret )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
if( shortkid )
|
||||
return G10ERR_UNSUPPORTED;
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate_by_keyid( rentry->dbf, kbpos, keyid );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Lock the keyblock; wait until it's available
|
||||
|
@ -502,7 +670,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
|||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
/* FIXME: make sure that there is only one enum at a time */
|
||||
kbpos->offset = 0;
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
|
@ -521,7 +690,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
|||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_enum( kbpos, ret_root );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
|
@ -548,11 +717,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
|||
kbpos->fp = NULL;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
}
|
||||
/* release pending packet */
|
||||
|
@ -583,7 +749,7 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
|
|||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_store( kbpos, root, 0 );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
|
@ -639,7 +805,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
|
|||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_store( kbpos, root, 1 );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
|
@ -1129,58 +1295,179 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
|||
********** Functions which operates on GDM files ***************
|
||||
****************************************************************/
|
||||
|
||||
#if MAX_FINGERPRINT_LEN > 20
|
||||
#error A GDBM keyring assumes that fingerprints are less than 21
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Insert the keyblock into the GDBM database
|
||||
*/
|
||||
|
||||
static int
|
||||
do_gdbm_store( KBPOS *kbpos, KBNODE root, int update )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
PKT_public_key *pk;
|
||||
KBNODE kbctx, node;
|
||||
IOBUF fp = NULL;
|
||||
byte fpr[20];
|
||||
byte contbuf[21];
|
||||
byte keybuf[21];
|
||||
size_t fprlen;
|
||||
datum key, content;
|
||||
int i, rc;
|
||||
|
||||
if( !(rentry = check_pos( kbpos )) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
/* construct the fingerprint which is used as the primary key */
|
||||
node = find_kbnode( root, PKT_PUBLIC_KEY );
|
||||
if( !node )
|
||||
log_bug("a gdbm database can't store secret keys\n");
|
||||
pk = node->pkt->pkt.public_key;
|
||||
|
||||
fingerprint_from_pk( pk, fpr, &fprlen );
|
||||
for(i=fprlen; i < DIM(fpr); i++ )
|
||||
fpr[i] = 0;
|
||||
|
||||
/* build the keyblock */
|
||||
kbctx=NULL;
|
||||
fp = iobuf_temp();
|
||||
iobuf_put( fp, 1 ); /* data is a keyblock */
|
||||
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
|
||||
if( (rc = build_packet( fp, node->pkt )) ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
/* store data and key */
|
||||
*keybuf = 1; /* key is a padded fingerprint */
|
||||
memcpy(keybuf+1, fpr, 20 );
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 21;
|
||||
content.dptr = iobuf_get_temp_buffer( fp );
|
||||
content.dsize = iobuf_get_temp_length( fp );
|
||||
rc = gdbm_store( rentry->dbf, key, content,
|
||||
update? GDBM_REPLACE : GDBM_INSERT );
|
||||
if( rc ) {
|
||||
log_error("%s: gdbm_store failed: %s\n", rentry->fname,
|
||||
rc == 1 ? "already stored"
|
||||
: gdbm_strerror(gdbm_errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
/* now store all keyids */
|
||||
*contbuf = 2; /* data is a list of fingerprints */
|
||||
memcpy(contbuf+1, fpr, 20 );
|
||||
content.dptr = contbuf;
|
||||
content.dsize= 21;
|
||||
kbctx=NULL;
|
||||
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
u32 aki[2];
|
||||
|
||||
keyid_from_pk( node->pkt->pkt.public_key, aki );
|
||||
*keybuf = 2; /* key is a 8 byte keyid */
|
||||
u32tobuf( keybuf+1 , aki[0] );
|
||||
u32tobuf( keybuf+5, aki[1] );
|
||||
key.dptr = keybuf;
|
||||
key.dsize= 9;
|
||||
/* fixme: must be more clever when a insert failed:
|
||||
* build a list of fingerprints in this case */
|
||||
rc = gdbm_store( rentry->dbf, key, content,
|
||||
update? GDBM_REPLACE : GDBM_INSERT );
|
||||
if( rc ) {
|
||||
log_info("%s: gdbm_store keyid failed: %s\n", rentry->fname,
|
||||
rc == 1 ? "already stored"
|
||||
: gdbm_strerror(gdbm_errno) );
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
iobuf_close(fp); /* don't need a cancel because it is a temp iobuf */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* search one keybox, return 0 if found, -1 if not found or an errorcode.
|
||||
*/
|
||||
static int
|
||||
do_gdbm_search( PACKET *req, KBPOS *kbpos, GDBM_FILE dbf, const char *fname )
|
||||
do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos, const byte *fpr, int fprlen )
|
||||
{
|
||||
byte *keybuf = kbpos->keybuf;
|
||||
datum key;
|
||||
int i;
|
||||
|
||||
*keybuf = 1;
|
||||
for(i=0; i < fprlen; i++ )
|
||||
keybuf[i+1] = fpr[i];
|
||||
for(; i < 20; i++ )
|
||||
keybuf[i+1] = 0;
|
||||
|
||||
/* fetch the data */
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 21;
|
||||
if( !gdbm_exists( dbf, key ) )
|
||||
return -1; /* not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************
|
||||
* locate by keyid.
|
||||
* FIXME: we must have a way to enumerate thru the list opf fingerprints
|
||||
*/
|
||||
static int
|
||||
do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
|
||||
{
|
||||
byte keybuf[9];
|
||||
datum key, content;
|
||||
int rc;
|
||||
PACKET pkt;
|
||||
int save_mode;
|
||||
ulong offset;
|
||||
int pkttype = req->pkttype;
|
||||
PKT_public_key *req_pk = req->pkt.public_key;
|
||||
PKT_secret_key *req_sk = req->pkt.secret_key;
|
||||
|
||||
init_packet(&pkt);
|
||||
save_mode = set_packet_list_mode(0);
|
||||
/* construct the fingerprint which is used as the primary key */
|
||||
*keybuf = 2;
|
||||
u32tobuf( keybuf+1, keyid[0] );
|
||||
u32tobuf( keybuf+5, keyid[1] );
|
||||
|
||||
/* fetch the data */
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 9;
|
||||
content = gdbm_fetch( dbf, key );
|
||||
if( !content.dptr )
|
||||
return -1;
|
||||
|
||||
while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
|
||||
if( pkt.pkttype == PKT_SECRET_KEY ) {
|
||||
PKT_secret_key *sk = pkt.pkt.secret_key;
|
||||
|
||||
if( req_sk->timestamp == sk->timestamp
|
||||
&& req_sk->pubkey_algo == sk->pubkey_algo
|
||||
&& !cmp_seckey( req_sk, sk) )
|
||||
break; /* found */
|
||||
}
|
||||
else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
|
||||
PKT_public_key *pk = pkt.pkt.public_key;
|
||||
|
||||
if( req_pk->timestamp == pk->timestamp
|
||||
&& req_pk->pubkey_algo == pk->pubkey_algo
|
||||
&& !cmp_pubkey( req_pk, pk ) )
|
||||
break; /* found */
|
||||
}
|
||||
else
|
||||
BUG();
|
||||
free_packet(&pkt);
|
||||
if( content.dsize < 2 ) {
|
||||
log_error("gdbm_fetch did not return enough data\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( !rc )
|
||||
kbpos->offset = offset;
|
||||
if( *content.dptr != 2 ) {
|
||||
log_error("gdbm_fetch returned unexpected type %d\n",
|
||||
*(byte*)content.dptr );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize < 21 ) {
|
||||
log_error("gdbm_fetch did not return a complete fingerprint\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize > 21 )
|
||||
log_info("gdbm_fetch: warning: more than one fingerprint\n" );
|
||||
|
||||
leave:
|
||||
free_packet(&pkt);
|
||||
set_packet_list_mode(save_mode);
|
||||
#if __MINGW32__
|
||||
iobuf_close(iobuf);
|
||||
#endif
|
||||
rc = do_gdbm_locate( dbf, kbpos, content.dptr+1, 20 );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
|
@ -1189,22 +1476,32 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
|||
RESTBL *rentry;
|
||||
KBNODE root = NULL;
|
||||
IOBUF a;
|
||||
int in_cert = 0;
|
||||
datum key, content;
|
||||
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
a = iobuf_fopen( rentry->fname, "rb" );
|
||||
if( !a ) {
|
||||
log_error("can't open '%s'\n", rentry->fname );
|
||||
return G10ERR_OPEN_FILE;
|
||||
key.dptr = kbpos->keybuf;
|
||||
key.dsize = 21;
|
||||
content = gdbm_fetch( rentry->dbf, key );
|
||||
if( !content.dptr ) {
|
||||
log_error("gdbm_fetch failed: %s\n", gdbm_strerror(gdbm_errno) );
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize < 2 ) {
|
||||
log_error("gdbm_fetch did not return enough data\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( *content.dptr != 1 ) {
|
||||
log_error("gdbm_fetch returned unexpected type %d\n",
|
||||
*(byte*)content.dptr );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
|
||||
if( iobuf_seek( a, kbpos->offset ) ) {
|
||||
log_error("can't seek to %lu\n", kbpos->offset);
|
||||
iobuf_close(a);
|
||||
return G10ERR_KEYRING_OPEN;
|
||||
}
|
||||
a = iobuf_temp_with_content( content.dptr+1, content.dsize-1 );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
|
@ -1214,7 +1511,7 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
|||
if( rc != G10ERR_UNKNOWN_PACKET ) {
|
||||
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
goto ready;
|
||||
break;
|
||||
}
|
||||
kbpos->count++;
|
||||
free_packet( pkt );
|
||||
|
@ -1222,27 +1519,16 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
|||
continue;
|
||||
}
|
||||
/* make a linked list of all packets */
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_KEY:
|
||||
case PKT_SECRET_KEY:
|
||||
if( in_cert )
|
||||
goto ready;
|
||||
in_cert = 1;
|
||||
default:
|
||||
kbpos->count++;
|
||||
if( !root )
|
||||
root = new_kbnode( pkt );
|
||||
else
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
kbpos->count++;
|
||||
if( !root )
|
||||
root = new_kbnode( pkt );
|
||||
else
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
}
|
||||
ready:
|
||||
if( rc == -1 && root )
|
||||
rc = 0;
|
||||
|
||||
if( rc )
|
||||
release_kbnode( root );
|
||||
else
|
||||
|
@ -1254,84 +1540,43 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
|||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Enum over keyblok data
|
||||
*/
|
||||
static int
|
||||
do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
|
||||
do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
PACKET *pkt;
|
||||
int rc;
|
||||
RESTBL *rentry;
|
||||
KBNODE root = NULL;
|
||||
datum key, helpkey;
|
||||
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
if( kbpos->pkt ) {
|
||||
root = new_kbnode( kbpos->pkt );
|
||||
kbpos->pkt = NULL;
|
||||
if( !kbpos->offset ) {
|
||||
kbpos->offset = 1;
|
||||
key = gdbm_firstkey( rentry->dbf );
|
||||
}
|
||||
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
|
||||
if( rc ) { /* ignore errors */
|
||||
if( rc != G10ERR_UNKNOWN_PACKET ) {
|
||||
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
goto ready;
|
||||
}
|
||||
free_packet( pkt );
|
||||
init_packet( pkt );
|
||||
continue;
|
||||
}
|
||||
/* make a linked list of all packets */
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_KEY:
|
||||
case PKT_SECRET_KEY:
|
||||
if( root ) { /* store this packet */
|
||||
kbpos->pkt = pkt;
|
||||
pkt = NULL;
|
||||
goto ready;
|
||||
}
|
||||
root = new_kbnode( pkt );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* skip pakets at the beginning of a keyring, until we find
|
||||
* a start packet; issue a warning if it is not a comment */
|
||||
if( !root && pkt->pkttype != PKT_COMMENT
|
||||
&& pkt->pkttype != PKT_OLD_COMMENT ) {
|
||||
log_info("keyring_enum: skipped packet of type %d\n",
|
||||
pkt->pkttype );
|
||||
break;
|
||||
}
|
||||
if( !root || (skipsigs && ( pkt->pkttype == PKT_SIGNATURE
|
||||
||pkt->pkttype == PKT_COMMENT
|
||||
||pkt->pkttype == PKT_OLD_COMMENT )) ) {
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
helpkey.dptr = kbpos->keybuf;
|
||||
helpkey.dsize= 21;
|
||||
key = gdbm_nextkey( rentry->dbf, helpkey );
|
||||
}
|
||||
ready:
|
||||
if( rc == -1 && root )
|
||||
rc = 0;
|
||||
while( key.dptr && (!key.dsize || *key.dptr != 1) ) {
|
||||
helpkey = key;
|
||||
key = gdbm_nextkey( rentry->dbf, helpkey );
|
||||
free( helpkey.dptr ); /* free and not m_free() ! */
|
||||
}
|
||||
if( !key.dptr )
|
||||
return -1; /* eof */
|
||||
|
||||
if( rc )
|
||||
release_kbnode( root );
|
||||
else
|
||||
*ret_root = root;
|
||||
free_packet( pkt );
|
||||
m_free( pkt );
|
||||
|
||||
return rc;
|
||||
if( key.dsize < 21 ) {
|
||||
free( key.dptr ); /* free and not m_free() ! */
|
||||
log_error("do_gdm_enum: key is too short\n" );
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
memcpy( kbpos->keybuf, key.dptr, 21 );
|
||||
free( key.dptr ); /* free and not m_free() ! */
|
||||
return do_gdbm_read( kbpos, ret_root );
|
||||
}
|
||||
|
||||
#endif /*HAVE_LIBGDBM*/
|
||||
|
||||
|
||||
|
|
|
@ -108,9 +108,6 @@ only_old_style( SK_LIST sk_list )
|
|||
SK_LIST sk_rover = NULL;
|
||||
int old_style = 0;
|
||||
|
||||
if( opt.force_v3_sigs )
|
||||
return 1;
|
||||
|
||||
/* if there are only old style capable key we use the old sytle */
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
|
@ -159,7 +156,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
int compr_algo = -1; /* unknown */
|
||||
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
memset( &mfx, 0, sizeof mfx);
|
||||
|
@ -181,6 +177,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
goto leave;
|
||||
if( !old_style )
|
||||
old_style = only_old_style( sk_list );
|
||||
|
||||
if( encrypt ) {
|
||||
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
|
||||
goto leave;
|
||||
|
@ -372,7 +369,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
/* build the signature packet */
|
||||
/* fixme: this code is partly duplicated in make_keysig_packet */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = old_style? 3 : sk->version;
|
||||
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
|
||||
keyid_from_sk( sk, sig->keyid );
|
||||
sig->digest_algo = hash_for(sk->pubkey_algo);
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
|
@ -608,7 +605,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|||
/* build the signature packet */
|
||||
/* fixme: this code is duplicated above */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = old_style? 3 : sk->version;
|
||||
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
|
||||
keyid_from_sk( sk, sig->keyid );
|
||||
sig->digest_algo = hash_for(sk->pubkey_algo);
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
|
|
148
g10/tdbio.c
148
g10/tdbio.c
|
@ -269,7 +269,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
|
||||
if( access( fname, R_OK ) ) {
|
||||
if( errno != ENOENT ) {
|
||||
log_error_f( fname, _("can't access: %s\n"), strerror(errno) );
|
||||
log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
|
||||
m_free(fname);
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
|
@ -289,17 +289,19 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
#endif
|
||||
log_fatal_f( fname, _("can't create directory: %s\n"),
|
||||
strerror(errno) );
|
||||
log_fatal( _("%s: can't create directory: %s\n"),
|
||||
fname, strerror(errno) );
|
||||
else
|
||||
log_info( _("%s: directory created\n"), fname );
|
||||
}
|
||||
else
|
||||
log_fatal_f(fname, _("directory does not exist!\n") );
|
||||
log_fatal( _("%s: directory does not exist!\n"), fname );
|
||||
}
|
||||
*p = '/';
|
||||
|
||||
fp =fopen( fname, "wb" );
|
||||
if( !fp )
|
||||
log_fatal_f( fname, _("can't create: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
|
||||
fclose(fp);
|
||||
m_free(db_name);
|
||||
db_name = fname;
|
||||
|
@ -309,7 +311,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
db_fd = open( db_name, O_RDWR );
|
||||
#endif
|
||||
if( db_fd == -1 )
|
||||
log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
|
||||
memset( &rec, 0, sizeof rec );
|
||||
rec.r.ver.version = 2;
|
||||
|
@ -320,11 +322,14 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
|||
if( !rc )
|
||||
tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( fname, _("failed to create version record: %s"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: failed to create version record: %s"),
|
||||
fname, g10_errstr(rc));
|
||||
/* and read again to check that we are okay */
|
||||
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
|
||||
log_fatal_f( db_name, "invalid trust-db created\n" );
|
||||
log_fatal( _("%s: invalid trust-db created\n"), db_name );
|
||||
|
||||
log_info(_("%s: trust-db created\n"), db_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -354,9 +359,9 @@ open_db()
|
|||
db_fd = open( db_name, O_RDWR );
|
||||
#endif
|
||||
if( db_fd == -1 )
|
||||
log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
|
||||
log_fatal_f( db_name, _("invalid trust-db\n") );
|
||||
log_fatal( _("%s: invalid trust-db\n"), db_name );
|
||||
/* fixme: check ->locked and other stuff */
|
||||
}
|
||||
|
||||
|
@ -390,16 +395,16 @@ create_hashtable( TRUSTREC *vr, int type )
|
|||
rec.recnum = recnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to create hashtable: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: failed to create hashtable: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
/* update the version record */
|
||||
rc = tdbio_write_record( vr );
|
||||
if( !rc )
|
||||
rc = tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error updating version record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: error updating version record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,8 +423,8 @@ get_keyhashrec()
|
|||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( !vr.r.ver.keyhashtbl )
|
||||
create_hashtable( &vr, 0 );
|
||||
|
||||
|
@ -443,8 +448,8 @@ get_sdirhashrec()
|
|||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( !vr.r.ver.sdirhashtbl )
|
||||
create_hashtable( &vr, 1 );
|
||||
|
||||
|
@ -744,14 +749,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
|||
rec->r.dir.uidlist,
|
||||
rec->r.dir.cacherec,
|
||||
rec->r.dir.ownertrust );
|
||||
if( rec->r.dir.dirflags & DIRF_ERROR )
|
||||
fputs(", error", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_CHECKED )
|
||||
fputs(", checked", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_MISKEY )
|
||||
fputs(", miskey", fp );
|
||||
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 );
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_KEY:
|
||||
|
@ -761,8 +766,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
|||
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_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
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:
|
||||
|
@ -772,12 +783,12 @@ 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_CHECKED )
|
||||
fputs(", checked", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_VALID )
|
||||
fputs(", valid", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
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:
|
||||
|
@ -795,9 +806,19 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
|||
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:%02x", rec->r.sig.sig[i].lid,
|
||||
rec->r.sig.sig[i].flag );
|
||||
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_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;
|
||||
|
@ -876,7 +897,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
break;
|
||||
case RECTYPE_VER: /* version record */
|
||||
if( memcmp(buf+1, "gpg", 3 ) ) {
|
||||
log_error_f( db_name, _("not a trustdb file\n") );
|
||||
log_error( _("%s: not a trustdb file\n"), db_name );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
p += 2; /* skip "pgp" */
|
||||
|
@ -890,12 +911,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
rec->r.ver.firstfree =buftoulong(p); p += 4;
|
||||
rec->r.ver.sdirhashtbl =buftoulong(p); p += 4;
|
||||
if( recnum ) {
|
||||
log_error_f( db_name, "version record with recnum %lu\n",
|
||||
log_error( _("%s: version record with recnum %lu\n"), db_name,
|
||||
(ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
else if( rec->r.ver.version != 2 ) {
|
||||
log_error_f( db_name, "invalid file version %d\n",
|
||||
log_error( _("%s: invalid file version %d\n"), db_name,
|
||||
rec->r.ver.version );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
|
@ -911,8 +932,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
rec->r.dir.ownertrust = *p++;
|
||||
rec->r.dir.dirflags = *p++;
|
||||
if( rec->r.dir.lid != recnum ) {
|
||||
log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
|
||||
rec->r.dir.lid, (ulong)recnum );
|
||||
log_error( "%s: dir LID != recnum (%lu,%lu)\n",
|
||||
db_name, rec->r.dir.lid, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
break;
|
||||
|
@ -957,8 +978,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
p += 3;
|
||||
rec->r.sdir.hintlist = buftoulong(p);
|
||||
if( rec->r.sdir.lid != recnum ) {
|
||||
log_error_f( db_name, "sdir LID != recnum (%lu,%lu)\n",
|
||||
rec->r.sdir.lid, (ulong)recnum );
|
||||
log_error( "%s: sdir LID != recnum (%lu,%lu)\n",
|
||||
db_name, rec->r.sdir.lid, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
break;
|
||||
|
@ -979,8 +1000,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
|||
}
|
||||
break;
|
||||
default:
|
||||
log_error_f( db_name, "invalid record type %d at recnum %lu\n",
|
||||
rec->rectype, (ulong)recnum );
|
||||
log_error( "%s: invalid record type %d at recnum %lu\n",
|
||||
db_name, rec->rectype, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
break;
|
||||
}
|
||||
|
@ -1122,8 +1143,8 @@ tdbio_delete_record( ulong recnum )
|
|||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
|
||||
rec.recnum = recnum;
|
||||
rec.rectype = RECTYPE_FREE;
|
||||
|
@ -1149,22 +1170,22 @@ tdbio_new_recnum()
|
|||
/* look for unused records */
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( vr.r.ver.firstfree ) {
|
||||
recnum = vr.r.ver.firstfree;
|
||||
rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
|
||||
if( rc ) {
|
||||
log_error_f( db_name, _("error reading free record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_error( _("%s: error reading free record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/* update dir record */
|
||||
vr.r.ver.firstfree = rec.r.free.next;
|
||||
rc = tdbio_write_record( &vr );
|
||||
if( rc ) {
|
||||
log_error_f( db_name, _("error writing dir record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_error( _("%s: error writing dir record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/*zero out the new record */
|
||||
|
@ -1173,8 +1194,8 @@ tdbio_new_recnum()
|
|||
rec.recnum = recnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to zero a record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal(_("%s: failed to zero a record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
else { /* not found, append a new record */
|
||||
offset = lseek( db_fd, 0, SEEK_END );
|
||||
|
@ -1203,8 +1224,8 @@ tdbio_new_recnum()
|
|||
}
|
||||
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to append a record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal(_("%s: failed to append a record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
return recnum ;
|
||||
}
|
||||
|
@ -1230,10 +1251,9 @@ tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec )
|
|||
|
||||
if( !rc ) {
|
||||
if( pk->local_id && pk->local_id != rec->recnum )
|
||||
log_error_f(db_name,
|
||||
"found record, but LID from memory does "
|
||||
log_error("%s: found record, but LID from memory does "
|
||||
"not match recnum (%lu,%lu)\n",
|
||||
pk->local_id, rec->recnum );
|
||||
db_name, pk->local_id, rec->recnum );
|
||||
pk->local_id = rec->recnum;
|
||||
}
|
||||
return rc;
|
||||
|
@ -1272,8 +1292,8 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
|
|||
/* Now read the dir record */
|
||||
rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
|
||||
if( rc )
|
||||
log_error_f(db_name, "can't read dirrec %lu: %s\n",
|
||||
recnum, g10_errstr(rc) );
|
||||
log_error("%s: can't read dirrec %lu: %s\n",
|
||||
db_name, recnum, g10_errstr(rc) );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
33
g10/tdbio.h
33
g10/tdbio.h
|
@ -21,6 +21,7 @@
|
|||
#ifndef G10_TDBIO_H
|
||||
#define G10_TDBIO_H
|
||||
|
||||
#include "host2net.h"
|
||||
|
||||
#define TRUST_RECORD_LEN 40
|
||||
#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
|
||||
|
@ -46,15 +47,14 @@
|
|||
#define RECTYPE_FREE 254
|
||||
|
||||
|
||||
#define DIRF_CHECKED 1 /* everything has been checked, the other bits are
|
||||
valid */
|
||||
#define DIRF_MISKEY 2 /* not all signatures are checked */
|
||||
/* this flag is used as a quick hint, that we */
|
||||
/* do not need to look at the sig records */
|
||||
#define DIRF_ERROR 4 /* severe errors: the key is not valid for some reasons
|
||||
but we mark it to avoid duplicate checks */
|
||||
#define DIRF_CHECKED 1 /* has been checkd - other bits 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 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 */
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
|||
|
||||
#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_NOPUBKEY 128 /* there is no pubkey for this sig */
|
||||
|
||||
|
@ -176,22 +177,4 @@ int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
|
|||
int tdbio_search_sdir( u32 *keyid, int pubkey_algo, TRUSTREC *rec );
|
||||
|
||||
|
||||
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
|
||||
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
|
||||
#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
|
||||
#define ulongtobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 24; \
|
||||
((byte*)p)[1] = a >> 16; \
|
||||
((byte*)p)[2] = a >> 8; \
|
||||
((byte*)p)[3] = a ; \
|
||||
} while(0)
|
||||
#define ushorttobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 8; \
|
||||
((byte*)p)[1] = a ; \
|
||||
} while(0)
|
||||
#define buftou32( p) buftoulong( (p) )
|
||||
#define u32tobuf( p, a) ulongtobuf( (p), (a) )
|
||||
|
||||
|
||||
|
||||
#endif /*G10_TDBIO_H*/
|
||||
|
|
|
@ -1370,6 +1370,8 @@ update_trustdb( )
|
|||
else
|
||||
log_info("lid %lu: updated\n",
|
||||
lid_from_keyblock(keyblock) );
|
||||
|
||||
release_kbnode( keyblock ); keyblock = NULL;
|
||||
}
|
||||
}
|
||||
if( rc && rc != -1 )
|
||||
|
@ -1910,7 +1912,6 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
|
|||
}
|
||||
if( recno ) { /* yes */
|
||||
ins_recno_list( recno_list, recno, RECTYPE_KEY );
|
||||
/* here we would compare/update the keyflags */
|
||||
}
|
||||
else { /* no: insert this new key */
|
||||
memset( &krec, 0, sizeof(krec) );
|
||||
|
@ -2110,6 +2111,8 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
|||
}
|
||||
}
|
||||
else if( sig->sig_class == 0x18 ) { /* key binding */
|
||||
/* get the corresponding key */
|
||||
|
||||
/* FIXME */
|
||||
}
|
||||
else if( sig->sig_class == 0x20 ) { /* key revocation */
|
||||
|
@ -2427,6 +2430,7 @@ update_trust_record( KBNODE keyblock )
|
|||
ulong uidrecno = 0;
|
||||
byte uidhash[20];
|
||||
RECNO_LIST recno_list = NULL; /* list of verified records */
|
||||
/* fixme: replace recno_list by a lookup on node->recno */
|
||||
|
||||
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
primary_pk = node->pkt->pkt.public_key;
|
||||
|
@ -2459,6 +2463,7 @@ update_trust_record( KBNODE keyblock )
|
|||
|
||||
case PKT_SIGNATURE:
|
||||
if( drec.dirty ) { /* upd_sig_recrod may read the drec */
|
||||
|
||||
write_record( &drec );
|
||||
drec.dirty = 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue