Epxerimenta support for GDBM keyings.

This commit is contained in:
Werner Koch 1998-10-21 17:34:36 +00:00
parent 6e16296864
commit e309a875cb
36 changed files with 1049 additions and 558 deletions

View File

@ -1,3 +1,16 @@
Wed Oct 21 17:24:24 1998 Werner Koch (wk@isil.d.shuttle.de)
* configure.in: Removed gettext kludge
* acinclude.m4: Add patched AM_WITH_NKS macro
Tue Oct 20 19:03:36 1998 Werner Koch (wk@isil.d.shuttle.de)
* configure.in: Kludge to make AM_GNU_GETTEXT work,
changed some macors to more modern versions. Also
changeg the all makefiles to remove duplicate ../intl.
* acinclude.m4: Removed the gettext stuff, as this
already comes with automake now.
Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* configure.in (NAME_OF_DEV_RANDOM): New.

15
NEWS
View File

@ -1,3 +1,18 @@
* Fixed the gettext configure bug.
* Kludge for RSA keys: keyid and length of a RSA key are
correctly reported, but you get an error if you try to use
this key (If you do not have the non-US version).
* Experimental support for keyrings stored in a GDBM database.
This is *much* faster than a standard keyring. You will notice
that the import gets slower with time; the reason is that all
new keys are used to verify signatures of previous inserted
keys. Use "--keyring gnupg-gdbm:<name-of-gdbm-file>". This is
not (yet) supported for secret keys.
Noteworthy changes in version 0.4.2
-----------------------------------

View File

@ -1,6 +1,10 @@
- abstraction of the MPI
* abstraction of the MPI
- Add a way to override the current cipher/md implementations
* Add a way to override the current cipher/md implementations
by others (using extensions)
* add a fast-import command which does not do the signature checks
of other keys (processing of the sdir hintlist). The signatures
may then be verified by a maintainence pass.

2
THANKS
View File

@ -17,6 +17,8 @@ Ed Boraas ecxjo@esperanto.org
Ernst Molitor ernst.molitor@uni-bonn.de
Frank Heckenbach heckenb@mi.uni-erlangen.de
Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
Gregory Steuck steuck@iname.com
Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org
Hugh Daniel hugh@toad.com

2
TODO
View File

@ -1,6 +1,4 @@
* There is a new memory leak in update-trustdb :-(
* Fix ;) revocation and expire stuff.
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but:

View File

@ -1 +1 @@
0.4.2
0.4.2a

View File

@ -209,83 +209,12 @@ define(WK_CHECK_MLOCK,
])
######################################################################
# progtest.m4 from gettext 0.35
######################################################################
# Search path for a program which passes the given test.
# Ulrich Drepper <drepper@cygnus.com>, 1996.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 1
dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
AC_DEFUN(AM_PATH_PROG_WITH_TEST,
[# Extract the first word of "$2", so it can be a program name with args.
set dummy $2; ac_word=[$]2
AC_MSG_CHECKING([for $ac_word])
AC_CACHE_VAL(ac_cv_path_$1,
[case "[$]$1" in
/*)
ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
;;
*)
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in ifelse([$5], , $PATH, [$5]); do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if [$3]; then
ac_cv_path_$1="$ac_dir/$ac_word"
break
fi
fi
done
IFS="$ac_save_ifs"
dnl If no 4th arg is given, leave the cache variable unset,
dnl so AC_PATH_PROGS will keep looking.
ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
])dnl
;;
esac])dnl
$1="$ac_cv_path_$1"
if test -n "[$]$1"; then
AC_MSG_RESULT([$]$1)
else
AC_MSG_RESULT(no)
fi
AC_SUBST($1)dnl
])
######################################################################
# lcmessage.m4 from gettext 0.35
######################################################################
# Check whether LC_MESSAGES is available in <locale.h>.
# Ulrich Drepper <drepper@cygnus.com>, 1995.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 1
AC_DEFUN(AM_LC_MESSAGES,
[if test $ac_cv_header_locale_h = yes; then
AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
[AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
if test $am_cv_val_LC_MESSAGES = yes; then
AC_DEFINE(HAVE_LC_MESSAGES)
fi
fi])
######################################################################
# gettext.m4 from gettext 0.35
######################################################################
# Macro to add for using GNU gettext.
# Ulrich Drepper <drepper@cygnus.com>, 1995.
#
@ -294,7 +223,7 @@ AC_DEFUN(AM_LC_MESSAGES,
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 5
# serial 5 + patch (wk 21.10.98)
AC_DEFUN(AM_WITH_NLS,
[AC_MSG_CHECKING([whether NLS is requested])
@ -334,14 +263,15 @@ AC_DEFUN(AM_WITH_NLS,
if test "$gt_cv_func_gettext_libc" != "yes"; then
AC_CHECK_LIB(intl, bindtextdomain,
[AC_CACHE_CHECK([for gettext in libintl],
gt_cv_func_gettext_libintl,
[AC_CHECK_LIB(intl, gettext,
gt_cv_func_gettext_libintl=yes,
gt_cv_func_gettext_libintl=no)],
[AC_CHECK_LIB(intl, gettext,
gt_cv_func_gettext_libintl=yes,
gt_cv_func_gettext_libintl=no)])
fi
if test "$gt_cv_func_gettext_libintl" = "yes" ; then
LIBS="-lintl $LIBS"
fi
if test "$gt_cv_func_gettext_libc" = "yes" \
|| test "$gt_cv_func_gettext_libintl" = "yes"; then
AC_DEFINE(HAVE_GETTEXT)
@ -481,6 +411,7 @@ AC_DEFUN(AM_WITH_NLS,
AC_SUBST(POSUB)
])
AC_DEFUN(AM_GNU_GETTEXT,
[AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AC_PROG_CC])dnl

View File

@ -1,3 +1,7 @@
Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
* pubkey.c: Hack to allow us to give some info about RSA keys back.
Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
* dynload.c: Support for DLD

View File

@ -2,7 +2,7 @@
gnupg_extensions = tiger twofish
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
noinst_LIBRARIES = libcipher.a
if ENABLE_GNUPG_EXTENSIONS

View File

@ -309,6 +309,8 @@ pubkey_get_npkey( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].npkey;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 2; /* see the RSA keyids */
return 0;
}
@ -324,6 +326,8 @@ pubkey_get_nskey( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nskey;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 6; /* see the RSA keyids */
return 0;
}
@ -339,6 +343,8 @@ pubkey_get_nsig( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nsig;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 1; /* see the RSA keyids */
return 0;
}
@ -354,6 +360,8 @@ pubkey_get_nenc( int algo )
if( pubkey_table[i].algo == algo )
return pubkey_table[i].nenc;
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* special hack, so that we are able to */
return 1; /* see the RSA keyids */
return 0;
}
@ -370,6 +378,8 @@ pubkey_nbits( int algo, MPI *pkey )
if( pubkey_table[i].algo == algo )
return (*pubkey_table[i].get_nbits)( algo, pkey );
} while( load_pubkey_modules() );
if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
return mpi_get_nbits( pkey[0] );
return 0;
}

View File

@ -3,6 +3,9 @@ dnl Configure template for GNUPG
dnl
dnl (Process this file with autoconf to produce a configure script.)
dnl Must reset CDPATH so that bash's cd does not print to stdout
CDPATH=
AC_INIT(g10/g10.c)
AC_CONFIG_AUX_DIR(scripts)
AM_CONFIG_HEADER(config.h)
@ -53,15 +56,12 @@ AC_ARG_WITH(included-zlib,
[g10_force_zlib=yes], [g10_force_zlib=no] )
AC_MSG_RESULT($g10_force_zlib)
AC_CANONICAL_SYSTEM
WK_CHECK_CACHE
dnl Checks for programs.
AC_PROG_MAKE_SET
AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM
AC_PROG_MAKE_SET
AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
@ -87,6 +87,12 @@ case "${target}" in
ac_cv_have_dev_random=no
AC_DEFINE(USE_RAND_W32)
;;
*-*-hpux*)
if test -z "$GCC" ; then
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
fi
AC_DEFINE(USE_RAND_UNIX)
;;
*)
AC_DEFINE(USE_RAND_UNIX)
;;
@ -124,6 +130,8 @@ AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
dnl Checks for libraries.
AM_GNU_GETTEXT
AC_CHECK_LIB(gdbm,gdbm_firstkey)
if test "$try_dynload" = yes ; then
@ -261,12 +269,8 @@ fi
fi
AC_SUBST(ZLIBS)
WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
WK_DO_LINK_FILES
AM_GNU_GETTEXT
AC_OUTPUT([
Makefile
@ -280,7 +284,5 @@ doc/Makefile
tools/Makefile
zlib/Makefile
checks/Makefile
],[echo timestamp >stamp-h; \
sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
])

View File

@ -349,6 +349,28 @@ There is one enhancement used with the old style packet headers:
+ that this is the last packet.
Usage of gdbm files for keyrings
================================
The key to store the keyblokc is it's fingerpint, other records
are used for secondary keys. fingerprints are always 20 bytes
where 16 bit fingerprints are appded with zero.
The first byte of the key gives some information on the type of the
key.
1 = key is a 20 bit fingerprint (16 bytes fpr are padded with zeroes)
data is the keyblock
2 = key is the complete 8 byte keyid
data is a list of 20 byte fingerprints
3 = key is the short 4 byte keyid
data is a list of 20 byte fingerprints
4 = key is the email address
data is a list of 20 byte fingerprints
Data is prepended with a type byte:
1 = keyblock
2 = list of 20 byte padded fingerprints
3 = list of list fingerprints (but how to we key them?)
Other Notes

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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 ) {

View File

@ -46,6 +46,7 @@ new_kbnode( PACKET *pkt )
n->pkt = pkt;
n->flag = 0;
n->private_flag=0;
n->recno = 0;
return n;
}

View File

@ -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 );

View File

@ -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;

View File

@ -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 )
{

View File

@ -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 ) {

View File

@ -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*/

View File

@ -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;

View File

@ -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;
}

View File

@ -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*/

View File

@ -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;
}

View File

@ -1,3 +1,7 @@
Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.h (iobuf_get_temp_buffer): New.
Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.h (iobuf_get): Now uses .nofast

View File

@ -7,6 +7,7 @@ ttyio.h
types.h
util.h
i18n.h
host2net.h
g10lib.h

43
include/host2net.h Normal file
View File

@ -0,0 +1,43 @@
/* host2net.h - Some macros
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNUPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifndef G10_HOST2NET_H
#define G10_HOST2NET_H
#include "types.h"
#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_HOST2NET_H*/

View File

@ -71,6 +71,7 @@ int iobuf_debug_mode;
IOBUF iobuf_alloc(int usage, size_t bufsize);
IOBUF iobuf_temp(void);
IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
IOBUF iobuf_open( const char *fname );
IOBUF iobuf_fopen( const char *fname, const char *mode );
IOBUF iobuf_create( const char *fname );
@ -129,6 +130,7 @@ int iobuf_in_block_mode( IOBUF a );
#define iobuf_where(a) "[don't know]"
#define iobuf_id(a) ((a)->no)
#define iobuf_get_temp_buffer(a) ( (a)->d.buf )
#define iobuf_get_temp_length(a) ( (a)->d.len )
#define iobuf_is_temp(a) ( (a)->usage == 3 )

View File

@ -9,19 +9,25 @@ if (autoconf --version) < /dev/null > /dev/null 2>&1 ; then
else
echo
echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM."
echo ' (version 2.10 or newer is required'
echo ' (version 2.10 or newer is required)'
DIE="yes"
fi
if (automake --version) < /dev/null > /dev/null 2>&1 ; then
if (aclocal --version) < /dev/null > /dev/null 2>&1; then
:
if (aclocal --version | awk 'NR==1 { if( $4 >= 1.3 ) exit 1; exit 0; }');
then
echo "**Error**: "\`aclocal\'" is too old."
echo ' (version 1.3 or newer is required)'
DIE="yes"
fi
else
echo
echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\'
echo " installed doesn't appear recent enough."
DIE="yes"
fi
else
echo
echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
@ -40,3 +46,5 @@ automake --gnu;
autoheader
autoconf
echo "Ready to run ./configure"

View File

@ -1,8 +1,8 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
INCLUDES = -I$(top_srcdir)/include
needed_libs = ../cipher/libcipher.a ../util/libutil.a \
../mpi/libmpi.a ../util/libutil.a
../mpi/libmpi.a ../util/libutil.a @INTLLIBS@
noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest
@ -15,10 +15,10 @@ mk_tdata_SOURCES = mk-tdata.c
shmtest_SOURCES = shmtest.c
mpicalc_LDADD = @INTLLIBS@ $(needed_libs)
bftest_LDADD = @INTLLIBS@ $(needed_libs)
mpicalc_LDADD = $(needed_libs)
bftest_LDADD = $(needed_libs)
shmtest_LDADD = @INTLLIBS@ $(needed_libs)
shmtest_LDADD = $(needed_libs)
mpicalc bftest shmtest: $(needed_libs)

View File

@ -1,3 +1,8 @@
Wed Oct 21 12:20:29 1998 Werner Koch (wk@isil.d.shuttle.de)
* util.c (iobuf_flush): autoincreasing of a temp. iobuf
(iobuf_temp_with_content): New.
Tue Oct 13 12:40:13 1998 Werner Koch (wk@isil.d.shuttle.de)
* util.c (.nofast): set this variable

View File

@ -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
noinst_LIBRARIES = libutil.a

View File

@ -483,6 +483,18 @@ iobuf_temp()
return a;
}
IOBUF
iobuf_temp_with_content( const char *buffer, size_t length )
{
IOBUF a;
a = iobuf_alloc(3, length );
memcpy( a->d.buf, buffer, length );
a->d.len = length;
return a;
}
/****************
* Create a head iobuf for reading from a file
@ -877,8 +889,19 @@ iobuf_flush(IOBUF a)
return 0;
/*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
if( a->usage == 3 )
log_bug("temp buffer too short\n");
if( a->usage == 3 ) { /* must increase the size of the temp buffer */
char *newbuf;
size_t newsize = a->d.size + 8192;
log_debug("increasing temp iobuf from %lu to %lu\n",
(ulong)a->d.size, (ulong)newsize );
newbuf = m_alloc( newsize );
memcpy( newbuf, a->d.buf, a->d.len );
m_free(a->d.buf);
a->d.buf = newbuf;
a->d.size = newsize;
return 0;
}
else if( a->usage != 2 )
log_bug("flush on non-output iobuf\n");
else if( !a->filter )

View File

@ -161,7 +161,7 @@ g10_log_bug( const char *fmt, ... )
va_list arg_ptr ;
putc('\n', stderr );
print_prefix("Ooops: ");
print_prefix("Ohhhh jeeee: ");
va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr);
@ -174,7 +174,7 @@ g10_log_bug( const char *fmt, ... )
void
g10_log_bug0( const char *file, int line, const char *func )
{
log_bug(_("Ohhhh jeeee ... this is a bug (%s:%d:%s)\n"), file, line, func );
log_bug(_("... this is a bug (%s:%d:%s)\n"), file, line, func );
}
#else
void