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) Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* configure.in (NAME_OF_DEV_RANDOM): New. * 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 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) 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 Ernst Molitor ernst.molitor@uni-bonn.de
Frank Heckenbach heckenb@mi.uni-erlangen.de Frank Heckenbach heckenb@mi.uni-erlangen.de
Gaël Quéri gqueri@mail.dotcom.fr Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
Gregory Steuck steuck@iname.com
Hendrik Buschkamp buschkamp@rheumanet.org Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org Holger Schurig holger@d.om.org
Hugh Daniel hugh@toad.com 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. * Fix ;) revocation and expire stuff.
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but: * 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. # Macro to add for using GNU gettext.
# Ulrich Drepper <drepper@cygnus.com>, 1995. # 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. # but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available. # 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_DEFUN(AM_WITH_NLS,
[AC_MSG_CHECKING([whether NLS is requested]) [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 if test "$gt_cv_func_gettext_libc" != "yes"; then
AC_CHECK_LIB(intl, bindtextdomain, AC_CHECK_LIB(intl, bindtextdomain,
[AC_CACHE_CHECK([for gettext in libintl], [AC_CHECK_LIB(intl, gettext,
gt_cv_func_gettext_libintl, gt_cv_func_gettext_libintl=yes,
[AC_CHECK_LIB(intl, gettext,
gt_cv_func_gettext_libintl=yes,
gt_cv_func_gettext_libintl=no)],
gt_cv_func_gettext_libintl=no)]) gt_cv_func_gettext_libintl=no)])
fi fi
if test "$gt_cv_func_gettext_libintl" = "yes" ; then
LIBS="-lintl $LIBS"
fi
if test "$gt_cv_func_gettext_libc" = "yes" \ if test "$gt_cv_func_gettext_libc" = "yes" \
|| test "$gt_cv_func_gettext_libintl" = "yes"; then || test "$gt_cv_func_gettext_libintl" = "yes"; then
AC_DEFINE(HAVE_GETTEXT) AC_DEFINE(HAVE_GETTEXT)
@ -481,6 +411,7 @@ AC_DEFUN(AM_WITH_NLS,
AC_SUBST(POSUB) AC_SUBST(POSUB)
]) ])
AC_DEFUN(AM_GNU_GETTEXT, AC_DEFUN(AM_GNU_GETTEXT,
[AC_REQUIRE([AC_PROG_MAKE_SET])dnl [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AC_PROG_CC])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) Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
* dynload.c: Support for DLD * dynload.c: Support for DLD

View File

@ -2,7 +2,7 @@
gnupg_extensions = tiger twofish 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 noinst_LIBRARIES = libcipher.a
if ENABLE_GNUPG_EXTENSIONS if ENABLE_GNUPG_EXTENSIONS

View File

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

View File

@ -3,6 +3,9 @@ dnl Configure template for GNUPG
dnl dnl
dnl (Process this file with autoconf to produce a configure script.) 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_INIT(g10/g10.c)
AC_CONFIG_AUX_DIR(scripts) AC_CONFIG_AUX_DIR(scripts)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
@ -53,15 +56,12 @@ AC_ARG_WITH(included-zlib,
[g10_force_zlib=yes], [g10_force_zlib=no] ) [g10_force_zlib=yes], [g10_force_zlib=no] )
AC_MSG_RESULT($g10_force_zlib) AC_MSG_RESULT($g10_force_zlib)
AC_CANONICAL_SYSTEM
WK_CHECK_CACHE
dnl Checks for programs. dnl Checks for programs.
AC_PROG_MAKE_SET AC_CANONICAL_SYSTEM
AC_ARG_PROGRAM AC_ARG_PROGRAM
AC_PROG_MAKE_SET
AM_SANITY_CHECK
missing_dir=`cd $ac_aux_dir && pwd` missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
@ -87,6 +87,12 @@ case "${target}" in
ac_cv_have_dev_random=no ac_cv_have_dev_random=no
AC_DEFINE(USE_RAND_W32) 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) AC_DEFINE(USE_RAND_UNIX)
;; ;;
@ -124,6 +130,8 @@ AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
dnl Checks for libraries. dnl Checks for libraries.
AM_GNU_GETTEXT
AC_CHECK_LIB(gdbm,gdbm_firstkey) AC_CHECK_LIB(gdbm,gdbm_firstkey)
if test "$try_dynload" = yes ; then if test "$try_dynload" = yes ; then
@ -261,12 +269,8 @@ fi
fi fi
AC_SUBST(ZLIBS) AC_SUBST(ZLIBS)
WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
WK_DO_LINK_FILES WK_DO_LINK_FILES
AM_GNU_GETTEXT
AC_OUTPUT([ AC_OUTPUT([
Makefile Makefile
@ -280,7 +284,5 @@ doc/Makefile
tools/Makefile tools/Makefile
zlib/Makefile zlib/Makefile
checks/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. + 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 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) Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* sign.c (only_old_style): Add option force_v3_sigs * 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 ## 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 EXTRA_DIST = OPTIONS pubring.asc
OMIT_DEPENDENCIES = zlib.h zconf.h OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@ LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
@ -76,7 +76,7 @@ gpgm_SOURCES = dearmor.c \
# $(common_source) # $(common_source)
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ LDADD = $(needed_libs) @ZLIBS@ @INTLLIBS@
gpgm_LDADD = g10maint.o $(LDADD) 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. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GNUPG. * 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; int rc;
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBNODE k;
KBPOS kbpos; KBPOS kbpos;
int oldmode = set_packet_list_mode(0); int oldmode = set_packet_list_mode(0);
byte namehash[20]; byte namehash[20];
int use_namehash=0; int use_namehash=0;
rc = enum_keyblocks( 0, &kbpos, &keyblock ); /* try the quick functions */
if( rc ) { k = NULL;
if( rc == -1 ) switch( mode ) {
rc = G10ERR_NO_PUBKEY; case 10:
else if( rc ) case 11:
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) ); rc = locate_keyblock_by_keyid( &kbpos, keyid, mode==10, 0 );
goto leave; 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 )) ) { /* if this was not possible, loop over all keyblocks
KBNODE k, kk; * fixme: If one of the resources in the quick functions above
if( mode < 10 ) { /* name lookup */ * works, but the key was not found, we will not find it
for(k=keyblock; k; k = k->next ) { * in the other resources */
if( k->pkt->pkttype == PKT_USER_ID if( rc == G10ERR_UNSUPPORTED ) {
&& !compare_name( k->pkt->pkt.user_id->name, rc = enum_keyblocks( 0, &kbpos, &keyblock );
k->pkt->pkt.user_id->len, name, mode)) { if( !rc ) {
/* we found a matching name, look for the key */ while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
for(kk=keyblock; kk; kk = kk->next ) { if( mode < 10 )
if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY k = find_by_name( keyblock, pk, name, mode,
|| kk->pkt->pkttype == PKT_PUBLIC_SUBKEY ) namehash, &use_namehash);
&& ( !pk->pubkey_algo else if( mode == 10 || mode == 11 )
|| pk->pubkey_algo k = find_by_keyid( keyblock, pk, keyid, mode );
== kk->pkt->pkt.public_key->pubkey_algo) else if( mode == 15 )
&& ( !pk->pubkey_usage k = find_first( keyblock, pk );
|| !check_pubkey_algo2( else if( mode == 16 || mode == 20 )
kk->pkt->pkt.public_key->pubkey_algo, k = find_by_fpr( keyblock, pk, name, mode );
pk->pubkey_usage )) else
) BUG();
break; if( k ) {
} finish_lookup( keyblock, pk, k, namehash,
if( kk ) { use_namehash, primary );
u32 aki[2]; break; /* found */
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");
} }
} release_kbnode( keyblock );
}
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;
keyblock = NULL; keyblock = NULL;
} }
break; /* enumeration */
} }
release_kbnode( keyblock ); enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
keyblock = NULL; 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: if( !rc ) {
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ if( ret_keyblock ) {
*ret_keyblock = keyblock;
keyblock = NULL;
}
}
else if( rc == -1 )
rc = G10ERR_NO_PUBKEY;
release_kbnode( keyblock ); release_kbnode( keyblock );
set_packet_list_mode(oldmode); set_packet_list_mode(oldmode);
if( opt.debug & DBG_MEMSTAT_VALUE ) { if( opt.debug & DBG_MEMSTAT_VALUE ) {

View File

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

View File

@ -46,6 +46,7 @@ struct kbnode_struct {
PACKET *pkt; PACKET *pkt;
int flag; int flag;
int private_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 */ int secret; /* working on a secret keyring */
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
GDBM_FILE dbf; GDBM_FILE dbf;
byte keybuf[21];
#endif #endif
PACKET *pkt; /* ditto */ 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 ); int add_keyblock_resource( const char *resname, int force, int secret );
const char *keyblock_resource_name( KBPOS *kbpos ); const char *keyblock_resource_name( KBPOS *kbpos );
int get_keyblock_handle( const char *filename, int secret, 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( PUBKEY_FIND_INFO info, KBPOS *kbpos );
int find_keyblock_byname( KBPOS *kbpos, const char *username ); int find_keyblock_byname( KBPOS *kbpos, const char *username );
int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk ); int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );

View File

@ -541,10 +541,18 @@ ask_expiredate()
static int static int
has_invalid_email_chars( const char *s ) has_invalid_email_chars( const char *s )
{ {
int at_seen=0;
for( ; *s; s++ ) { for( ; *s; s++ ) {
if( *s & 0x80 ) if( *s & 0x80 )
return 1; 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 1;
} }
return 0; return 0;

View File

@ -37,6 +37,7 @@
static void list_all(int); static void list_all(int);
static void list_one(const char *name, int secret); 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 ); static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
@ -70,63 +71,87 @@ secret_key_list( int nnames, char **names )
static void static void
list_all( int secret ) list_all( int secret )
{ {
int i, seq=0; KBPOS kbpos;
const char *s; KBNODE keyblock = NULL;
IOBUF a; int rc=0;
int lastresno;
/* FIXME: this assumes a keyring resource is a plain keyring file */ rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
while( (s = enum_keyblock_resources( &seq, secret )) ) { if( rc ) {
if( !(a = iobuf_open(s)) ) { if( rc != -1 )
log_error(_("can't open %s: %s\n"), s, strerror(errno)); log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
continue; goto leave;
}
if( seq > 1 )
putchar('\n');
printf("%s\n", s );
for(i=strlen(s); i; i-- )
putchar('-');
putchar('\n');
proc_packets( a );
iobuf_close(a);
} }
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 static void
list_one( const char *name, int secret ) list_one( const char *name, int secret )
{ {
int rc = 0; int rc = 0;
KBNODE keyblock = NULL; 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 kbctx;
KBNODE node; KBNODE node;
KBPOS kbpos;
PKT_public_key *pk; PKT_public_key *pk;
PKT_secret_key *sk; PKT_secret_key *sk;
u32 keyid[2]; u32 keyid[2];
int any=0; int any=0;
int trustletter = 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 */ /* get the keyid from the keyblock */
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
if( !node ) { if( !node ) {
log_error("Oops; key lost!\n"); log_error("Oops; key lost!\n");
goto leave; return;
} }
if( secret ) { if( secret ) {
@ -336,12 +361,10 @@ list_one( const char *name, int secret )
putchar(':'); putchar(':');
putchar('\n'); putchar('\n');
} }
leave:
release_kbnode( keyblock );
} }
static void static void
fingerprint( PKT_public_key *pk, PKT_secret_key *sk ) 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->local_id = 0;
c->trustletter = ' '; c->trustletter = ' ';
if( node->pkt->pkttype == PKT_PUBLIC_KEY 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 ); 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 ); list_node( c, node );
}
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) { else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
/* check all signatures */ /* check all signatures */
if( !c->have_data ) { if( !c->have_data ) {

View File

@ -35,8 +35,6 @@
* *
* - Delete a key block * - 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 "mpi.h"
#include "iobuf.h" #include "iobuf.h"
#include "keydb.h" #include "keydb.h"
#include "host2net.h"
#include "options.h" #include "options.h"
#include "i18n.h" #include "i18n.h"
#undef HAVE_LIBGDBM /* <--- not ready */
struct resource_table_struct { struct resource_table_struct {
int used; 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_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root ); 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 * static RESTBL *
@ -100,6 +106,14 @@ check_pos( KBPOS *kbpos )
return resource_table + kbpos->resno; 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 **************************** ****************** public functions ****************************
@ -188,9 +202,33 @@ add_keyblock_resource( const char *url, int force, int secret )
goto leave; 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 ) { switch( rt ) {
case rt_UNKNOWN: case rt_UNKNOWN:
log_error("%s: unknown resource type\n", url );
rc = G10ERR_GENERAL;
goto leave;
case rt_RING: case rt_RING:
iobuf = iobuf_fopen( filename, "rb" ); iobuf = iobuf_fopen( filename, "rb" );
if( !iobuf && !force ) { if( !iobuf && !force ) {
@ -199,20 +237,46 @@ add_keyblock_resource( const char *url, int force, int secret )
} }
if( !iobuf ) { 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 ); iobuf = iobuf_create( filename );
if( !iobuf ) { 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; rc = G10ERR_OPEN_FILE;
goto leave; goto leave;
} }
else else
log_info("%s: keyring created\n", filename ); 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__ #ifdef __MINGW32__
/* must close it again */ /* must close it again */
iobuf_close( iobuf ); iobuf_close( iobuf );
@ -222,6 +286,17 @@ add_keyblock_resource( const char *url, int force, int secret )
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM: 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; break;
#endif #endif
@ -310,14 +385,21 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
resource_table[i].fname ); resource_table[i].fname );
break; break;
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM case rt_GDBM: {
rc = do_gdbm_search( pkt, kbpos, resource_table[i].dbf, PKT_public_key *req_pk = pkt->pkt.public_key;
resource_table[i].fname ); 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; break;
#endif #endif
default: BUG(); default: BUG();
} }
kbpos->rt = resource_table[i].rt;
if( !rc ) { if( !rc ) {
kbpos->resno = i; kbpos->resno = i;
kbpos->fp = NULL; 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 * Lock the keyblock; wait until it's available
@ -502,7 +670,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
break; break;
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM: case rt_GDBM:
/* FIXME!!!! */ /* FIXME: make sure that there is only one enum at a time */
kbpos->offset = 0;
break; break;
#endif #endif
default: BUG(); default: BUG();
@ -521,7 +690,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
break; break;
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM: case rt_GDBM:
/* FIXME!!!! */ rc = do_gdbm_enum( kbpos, ret_root );
break; break;
#endif #endif
default: BUG(); default: BUG();
@ -548,11 +717,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
kbpos->fp = NULL; kbpos->fp = NULL;
} }
break; break;
#ifdef HAVE_LIBGDBM
case rt_GDBM: case rt_GDBM:
/* FIXME!!!! */
break; break;
#endif
default: BUG(); default: BUG();
} }
/* release pending packet */ /* release pending packet */
@ -583,7 +749,7 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
break; break;
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM: case rt_GDBM:
/* FIXME!!!! */ rc = do_gdbm_store( kbpos, root, 0 );
break; break;
#endif #endif
default: BUG(); default: BUG();
@ -639,7 +805,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
break; break;
#ifdef HAVE_LIBGDBM #ifdef HAVE_LIBGDBM
case rt_GDBM: case rt_GDBM:
/* FIXME!!!! */ rc = do_gdbm_store( kbpos, root, 1 );
break; break;
#endif #endif
default: BUG(); default: BUG();
@ -1129,58 +1295,179 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
********** Functions which operates on GDM files *************** ********** 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. * search one keybox, return 0 if found, -1 if not found or an errorcode.
*/ */
static int 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; 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); /* construct the fingerprint which is used as the primary key */
save_mode = set_packet_list_mode(0); *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( content.dsize < 2 ) {
if( pkt.pkttype == PKT_SECRET_KEY ) { log_error("gdbm_fetch did not return enough data\n" );
PKT_secret_key *sk = pkt.pkt.secret_key; free( content.dptr ); /* can't use m_free() here */
return G10ERR_INV_KEYRING;
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( !rc ) if( *content.dptr != 2 ) {
kbpos->offset = offset; 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: rc = do_gdbm_locate( dbf, kbpos, content.dptr+1, 20 );
free_packet(&pkt); free( content.dptr ); /* can't use m_free() here */
set_packet_list_mode(save_mode);
#if __MINGW32__
iobuf_close(iobuf);
#endif
return rc; return rc;
} }
static int static int
do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root ) do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
{ {
@ -1189,22 +1476,32 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
RESTBL *rentry; RESTBL *rentry;
KBNODE root = NULL; KBNODE root = NULL;
IOBUF a; IOBUF a;
int in_cert = 0; datum key, content;
if( !(rentry=check_pos(kbpos)) ) if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL; return G10ERR_GENERAL;
a = iobuf_fopen( rentry->fname, "rb" ); key.dptr = kbpos->keybuf;
if( !a ) { key.dsize = 21;
log_error("can't open '%s'\n", rentry->fname ); content = gdbm_fetch( rentry->dbf, key );
return G10ERR_OPEN_FILE; 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 ) ) { a = iobuf_temp_with_content( content.dptr+1, content.dsize-1 );
log_error("can't seek to %lu\n", kbpos->offset); free( content.dptr ); /* can't use m_free() here */
iobuf_close(a);
return G10ERR_KEYRING_OPEN;
}
pkt = m_alloc( sizeof *pkt ); pkt = m_alloc( sizeof *pkt );
init_packet(pkt); init_packet(pkt);
@ -1214,7 +1511,7 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
if( rc != G10ERR_UNKNOWN_PACKET ) { if( rc != G10ERR_UNKNOWN_PACKET ) {
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) ); log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
rc = G10ERR_INV_KEYRING; rc = G10ERR_INV_KEYRING;
goto ready; break;
} }
kbpos->count++; kbpos->count++;
free_packet( pkt ); free_packet( pkt );
@ -1222,27 +1519,16 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
continue; continue;
} }
/* make a linked list of all packets */ /* make a linked list of all packets */
switch( pkt->pkttype ) { kbpos->count++;
case PKT_PUBLIC_KEY: if( !root )
case PKT_SECRET_KEY: root = new_kbnode( pkt );
if( in_cert ) else
goto ready; add_kbnode( root, new_kbnode( pkt ) );
in_cert = 1; pkt = m_alloc( sizeof *pkt );
default: init_packet(pkt);
kbpos->count++;
if( !root )
root = new_kbnode( pkt );
else
add_kbnode( root, new_kbnode( pkt ) );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;
}
} }
ready:
if( rc == -1 && root ) if( rc == -1 && root )
rc = 0; rc = 0;
if( rc ) if( rc )
release_kbnode( root ); release_kbnode( root );
else else
@ -1254,84 +1540,43 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
} }
/****************
* Enum over keyblok data
*/
static int 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; RESTBL *rentry;
KBNODE root = NULL; datum key, helpkey;
if( !(rentry=check_pos(kbpos)) ) if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL; return G10ERR_GENERAL;
if( kbpos->pkt ) { if( !kbpos->offset ) {
root = new_kbnode( kbpos->pkt ); kbpos->offset = 1;
kbpos->pkt = NULL; key = gdbm_firstkey( rentry->dbf );
} }
else {
pkt = m_alloc( sizeof *pkt ); helpkey.dptr = kbpos->keybuf;
init_packet(pkt); helpkey.dsize= 21;
while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) { key = gdbm_nextkey( rentry->dbf, helpkey );
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;
}
} }
ready: while( key.dptr && (!key.dsize || *key.dptr != 1) ) {
if( rc == -1 && root ) helpkey = key;
rc = 0; key = gdbm_nextkey( rentry->dbf, helpkey );
free( helpkey.dptr ); /* free and not m_free() ! */
}
if( !key.dptr )
return -1; /* eof */
if( rc ) if( key.dsize < 21 ) {
release_kbnode( root ); free( key.dptr ); /* free and not m_free() ! */
else log_error("do_gdm_enum: key is too short\n" );
*ret_root = root; return G10ERR_INV_KEYRING;
free_packet( pkt ); }
m_free( pkt ); memcpy( kbpos->keybuf, key.dptr, 21 );
free( key.dptr ); /* free and not m_free() ! */
return rc; return do_gdbm_read( kbpos, ret_root );
} }
#endif /*HAVE_LIBGDBM*/ #endif /*HAVE_LIBGDBM*/

View File

@ -108,9 +108,6 @@ only_old_style( SK_LIST sk_list )
SK_LIST sk_rover = NULL; SK_LIST sk_rover = NULL;
int old_style = 0; int old_style = 0;
if( opt.force_v3_sigs )
return 1;
/* if there are only old style capable key we use the old sytle */ /* 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 ) { for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk; PKT_secret_key *sk = sk_rover->sk;
@ -159,7 +156,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
int compr_algo = -1; /* unknown */ int compr_algo = -1; /* unknown */
memset( &afx, 0, sizeof afx); memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx); memset( &zfx, 0, sizeof zfx);
memset( &mfx, 0, sizeof mfx); memset( &mfx, 0, sizeof mfx);
@ -181,6 +177,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
goto leave; goto leave;
if( !old_style ) if( !old_style )
old_style = only_old_style( sk_list ); old_style = only_old_style( sk_list );
if( encrypt ) { if( encrypt ) {
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) ) if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
goto leave; goto leave;
@ -372,7 +369,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
/* build the signature packet */ /* build the signature packet */
/* fixme: this code is partly duplicated in make_keysig_packet */ /* fixme: this code is partly duplicated in make_keysig_packet */
sig = m_alloc_clear( sizeof *sig ); 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 ); keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo); sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = 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 */ /* build the signature packet */
/* fixme: this code is duplicated above */ /* fixme: this code is duplicated above */
sig = m_alloc_clear( sizeof *sig ); 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 ); keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo); sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = 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( access( fname, R_OK ) ) {
if( errno != ENOENT ) { 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); m_free(fname);
return G10ERR_TRUSTDB; return G10ERR_TRUSTDB;
} }
@ -289,17 +289,19 @@ tdbio_set_dbname( const char *new_dbname, int create )
#else #else
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
#endif #endif
log_fatal_f( fname, _("can't create directory: %s\n"), log_fatal( _("%s: can't create directory: %s\n"),
strerror(errno) ); fname, strerror(errno) );
else
log_info( _("%s: directory created\n"), fname );
} }
else else
log_fatal_f(fname, _("directory does not exist!\n") ); log_fatal( _("%s: directory does not exist!\n"), fname );
} }
*p = '/'; *p = '/';
fp =fopen( fname, "wb" ); fp =fopen( fname, "wb" );
if( !fp ) 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); fclose(fp);
m_free(db_name); m_free(db_name);
db_name = fname; db_name = fname;
@ -309,7 +311,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
db_fd = open( db_name, O_RDWR ); db_fd = open( db_name, O_RDWR );
#endif #endif
if( db_fd == -1 ) 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 ); memset( &rec, 0, sizeof rec );
rec.r.ver.version = 2; rec.r.ver.version = 2;
@ -320,11 +322,14 @@ tdbio_set_dbname( const char *new_dbname, int create )
if( !rc ) if( !rc )
tdbio_sync(); tdbio_sync();
if( rc ) if( rc )
log_fatal_f( fname, _("failed to create version record: %s"), log_fatal( _("%s: failed to create version record: %s"),
g10_errstr(rc)); fname, g10_errstr(rc));
/* and read again to check that we are okay */ /* and read again to check that we are okay */
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) 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; return 0;
} }
} }
@ -354,9 +359,9 @@ open_db()
db_fd = open( db_name, O_RDWR ); db_fd = open( db_name, O_RDWR );
#endif #endif
if( db_fd == -1 ) 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 ) ) 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 */ /* fixme: check ->locked and other stuff */
} }
@ -390,16 +395,16 @@ create_hashtable( TRUSTREC *vr, int type )
rec.recnum = recnum; rec.recnum = recnum;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) if( rc )
log_fatal_f(db_name,_("failed to create hashtable: %s\n"), log_fatal( _("%s: failed to create hashtable: %s\n"),
g10_errstr(rc)); db_name, g10_errstr(rc));
} }
/* update the version record */ /* update the version record */
rc = tdbio_write_record( vr ); rc = tdbio_write_record( vr );
if( !rc ) if( !rc )
rc = tdbio_sync(); rc = tdbio_sync();
if( rc ) if( rc )
log_fatal_f( db_name, _("error updating version record: %s\n"), log_fatal( _("%s: error updating version record: %s\n"),
g10_errstr(rc)); db_name, g10_errstr(rc));
} }
@ -418,8 +423,8 @@ get_keyhashrec()
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal_f( db_name, _("error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
if( !vr.r.ver.keyhashtbl ) if( !vr.r.ver.keyhashtbl )
create_hashtable( &vr, 0 ); create_hashtable( &vr, 0 );
@ -443,8 +448,8 @@ get_sdirhashrec()
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal_f( db_name, _("error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
if( !vr.r.ver.sdirhashtbl ) if( !vr.r.ver.sdirhashtbl )
create_hashtable( &vr, 1 ); create_hashtable( &vr, 1 );
@ -744,14 +749,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
rec->r.dir.uidlist, rec->r.dir.uidlist,
rec->r.dir.cacherec, rec->r.dir.cacherec,
rec->r.dir.ownertrust ); rec->r.dir.ownertrust );
if( rec->r.dir.dirflags & DIRF_ERROR ) if( rec->r.dir.dirflags & DIRF_CHECKED ) {
fputs(", error", fp ); if( rec->r.dir.dirflags & DIRF_VALID )
if( rec->r.dir.dirflags & DIRF_CHECKED ) fputs(", valid", fp );
fputs(", checked", fp ); if( rec->r.dir.dirflags & DIRF_EXPIRED )
if( rec->r.dir.dirflags & DIRF_REVOKED ) fputs(", expired", fp );
fputs(", revoked", fp ); if( rec->r.dir.dirflags & DIRF_REVOKED )
if( rec->r.dir.dirflags & DIRF_MISKEY ) fputs(", revoked", fp );
fputs(", miskey", fp ); }
putc('\n', fp); putc('\n', fp);
break; break;
case RECTYPE_KEY: case RECTYPE_KEY:
@ -761,8 +766,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
rec->r.key.pubkey_algo ); rec->r.key.pubkey_algo );
for(i=0; i < rec->r.key.fingerprint_len; i++ ) for(i=0; i < rec->r.key.fingerprint_len; i++ )
fprintf(fp, "%02X", rec->r.key.fingerprint[i] ); fprintf(fp, "%02X", rec->r.key.fingerprint[i] );
if( rec->r.key.keyflags & KEYF_REVOKED ) if( rec->r.key.keyflags & KEYF_CHECKED ) {
fputs(", revoked", fp ); 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); putc('\n', fp);
break; break;
case RECTYPE_UID: case RECTYPE_UID:
@ -772,12 +783,12 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
rec->r.uid.prefrec, rec->r.uid.prefrec,
rec->r.uid.siglist, rec->r.uid.siglist,
rec->r.uid.namehash[18], rec->r.uid.namehash[19]); rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
if( rec->r.uid.uidflags & UIDF_CHECKED ) if( rec->r.uid.uidflags & UIDF_CHECKED ) {
fputs(", checked", fp ); if( rec->r.uid.uidflags & UIDF_VALID )
if( rec->r.uid.uidflags & UIDF_VALID ) fputs(", valid", fp );
fputs(", valid", fp ); if( rec->r.uid.uidflags & UIDF_REVOKED )
if( rec->r.uid.uidflags & UIDF_REVOKED ) fputs(", revoked", fp );
fputs(", revoked", fp ); }
putc('\n', fp); putc('\n', fp);
break; break;
case RECTYPE_PREF: case RECTYPE_PREF:
@ -795,9 +806,19 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
fprintf(fp, "sig %lu, next=%lu,", fprintf(fp, "sig %lu, next=%lu,",
rec->r.sig.lid, rec->r.sig.next ); rec->r.sig.lid, rec->r.sig.next );
for(i=0; i < SIGS_PER_RECORD; i++ ) { for(i=0; i < SIGS_PER_RECORD; i++ ) {
if( rec->r.sig.sig[i].lid ) if( rec->r.sig.sig[i].lid ) {
fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].lid, fprintf(fp, " %lu:", rec->r.sig.sig[i].lid );
rec->r.sig.sig[i].flag ); 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); putc('\n', fp);
break; break;
@ -876,7 +897,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
break; break;
case RECTYPE_VER: /* version record */ case RECTYPE_VER: /* version record */
if( memcmp(buf+1, "gpg", 3 ) ) { 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; rc = G10ERR_TRUSTDB;
} }
p += 2; /* skip "pgp" */ 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.firstfree =buftoulong(p); p += 4;
rec->r.ver.sdirhashtbl =buftoulong(p); p += 4; rec->r.ver.sdirhashtbl =buftoulong(p); p += 4;
if( recnum ) { 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 ); (ulong)recnum );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
else if( rec->r.ver.version != 2 ) { 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 ); rec->r.ver.version );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
@ -911,8 +932,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
rec->r.dir.ownertrust = *p++; rec->r.dir.ownertrust = *p++;
rec->r.dir.dirflags = *p++; rec->r.dir.dirflags = *p++;
if( rec->r.dir.lid != recnum ) { if( rec->r.dir.lid != recnum ) {
log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n", log_error( "%s: dir LID != recnum (%lu,%lu)\n",
rec->r.dir.lid, (ulong)recnum ); db_name, rec->r.dir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
break; break;
@ -957,8 +978,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
p += 3; p += 3;
rec->r.sdir.hintlist = buftoulong(p); rec->r.sdir.hintlist = buftoulong(p);
if( rec->r.sdir.lid != recnum ) { if( rec->r.sdir.lid != recnum ) {
log_error_f( db_name, "sdir LID != recnum (%lu,%lu)\n", log_error( "%s: sdir LID != recnum (%lu,%lu)\n",
rec->r.sdir.lid, (ulong)recnum ); db_name, rec->r.sdir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
} }
break; break;
@ -979,8 +1000,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
} }
break; break;
default: default:
log_error_f( db_name, "invalid record type %d at recnum %lu\n", log_error( "%s: invalid record type %d at recnum %lu\n",
rec->rectype, (ulong)recnum ); db_name, rec->rectype, (ulong)recnum );
rc = G10ERR_TRUSTDB; rc = G10ERR_TRUSTDB;
break; break;
} }
@ -1122,8 +1143,8 @@ tdbio_delete_record( ulong recnum )
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal_f( db_name, _("error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
rec.recnum = recnum; rec.recnum = recnum;
rec.rectype = RECTYPE_FREE; rec.rectype = RECTYPE_FREE;
@ -1149,22 +1170,22 @@ tdbio_new_recnum()
/* look for unused records */ /* look for unused records */
rc = tdbio_read_record( 0, &vr, RECTYPE_VER ); rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
if( rc ) if( rc )
log_fatal_f( db_name, _("error reading version record: %s\n"), log_fatal( _("%s: error reading version record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
if( vr.r.ver.firstfree ) { if( vr.r.ver.firstfree ) {
recnum = vr.r.ver.firstfree; recnum = vr.r.ver.firstfree;
rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE ); rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
if( rc ) { if( rc ) {
log_error_f( db_name, _("error reading free record: %s\n"), log_error( _("%s: error reading free record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
return rc; return rc;
} }
/* update dir record */ /* update dir record */
vr.r.ver.firstfree = rec.r.free.next; vr.r.ver.firstfree = rec.r.free.next;
rc = tdbio_write_record( &vr ); rc = tdbio_write_record( &vr );
if( rc ) { if( rc ) {
log_error_f( db_name, _("error writing dir record: %s\n"), log_error( _("%s: error writing dir record: %s\n"),
g10_errstr(rc) ); db_name, g10_errstr(rc) );
return rc; return rc;
} }
/*zero out the new record */ /*zero out the new record */
@ -1173,8 +1194,8 @@ tdbio_new_recnum()
rec.recnum = recnum; rec.recnum = recnum;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) if( rc )
log_fatal_f(db_name,_("failed to zero a record: %s\n"), log_fatal(_("%s: failed to zero a record: %s\n"),
g10_errstr(rc)); db_name, g10_errstr(rc));
} }
else { /* not found, append a new record */ else { /* not found, append a new record */
offset = lseek( db_fd, 0, SEEK_END ); offset = lseek( db_fd, 0, SEEK_END );
@ -1203,8 +1224,8 @@ tdbio_new_recnum()
} }
if( rc ) if( rc )
log_fatal_f(db_name,_("failed to append a record: %s\n"), log_fatal(_("%s: failed to append a record: %s\n"),
g10_errstr(rc)); db_name, g10_errstr(rc));
} }
return recnum ; return recnum ;
} }
@ -1230,10 +1251,9 @@ tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec )
if( !rc ) { if( !rc ) {
if( pk->local_id && pk->local_id != rec->recnum ) if( pk->local_id && pk->local_id != rec->recnum )
log_error_f(db_name, log_error("%s: found record, but LID from memory does "
"found record, but LID from memory does "
"not match recnum (%lu,%lu)\n", "not match recnum (%lu,%lu)\n",
pk->local_id, rec->recnum ); db_name, pk->local_id, rec->recnum );
pk->local_id = rec->recnum; pk->local_id = rec->recnum;
} }
return rc; return rc;
@ -1272,8 +1292,8 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
/* Now read the dir record */ /* Now read the dir record */
rc = tdbio_read_record( recnum, rec, RECTYPE_DIR); rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
if( rc ) if( rc )
log_error_f(db_name, "can't read dirrec %lu: %s\n", log_error("%s: can't read dirrec %lu: %s\n",
recnum, g10_errstr(rc) ); db_name, recnum, g10_errstr(rc) );
} }
return rc; return rc;
} }

View File

@ -21,6 +21,7 @@
#ifndef G10_TDBIO_H #ifndef G10_TDBIO_H
#define G10_TDBIO_H #define G10_TDBIO_H
#include "host2net.h"
#define TRUST_RECORD_LEN 40 #define TRUST_RECORD_LEN 40
#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5) #define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
@ -46,15 +47,14 @@
#define RECTYPE_FREE 254 #define RECTYPE_FREE 254
#define DIRF_CHECKED 1 /* everything has been checked, the other bits are #define DIRF_CHECKED 1 /* has been checkd - other bits are valid */
valid */ #define DIRF_VALID 2 /* This key is valid: There is at least */
#define DIRF_MISKEY 2 /* not all signatures are checked */ /* one uid with a selfsignature or an revocation */
/* this flag is used as a quick hint, that we */ #define DIRF_EXPIRED 4 /* the complete key has expired */
/* 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_REVOKED 8 /* the complete key has been revoked */ #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_EXPIRED 4 /* this key is expired */
#define KEYF_REVOKED 8 /* this key has been revoked */ #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_CHECKED 1 /* signature has been checked - bits 0..6 are valid */
#define SIGF_VALID 2 /* the signature is 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_REVOKED 8 /* this signature has been revoked */
#define SIGF_NOPUBKEY 128 /* there is no pubkey for this sig */ #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 ); 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*/ #endif /*G10_TDBIO_H*/

View File

@ -1370,6 +1370,8 @@ update_trustdb( )
else else
log_info("lid %lu: updated\n", log_info("lid %lu: updated\n",
lid_from_keyblock(keyblock) ); lid_from_keyblock(keyblock) );
release_kbnode( keyblock ); keyblock = NULL;
} }
} }
if( rc && rc != -1 ) if( rc && rc != -1 )
@ -1910,7 +1912,6 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
} }
if( recno ) { /* yes */ if( recno ) { /* yes */
ins_recno_list( recno_list, recno, RECTYPE_KEY ); ins_recno_list( recno_list, recno, RECTYPE_KEY );
/* here we would compare/update the keyflags */
} }
else { /* no: insert this new key */ else { /* no: insert this new key */
memset( &krec, 0, sizeof(krec) ); 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 */ else if( sig->sig_class == 0x18 ) { /* key binding */
/* get the corresponding key */
/* FIXME */ /* FIXME */
} }
else if( sig->sig_class == 0x20 ) { /* key revocation */ else if( sig->sig_class == 0x20 ) { /* key revocation */
@ -2427,6 +2430,7 @@ update_trust_record( KBNODE keyblock )
ulong uidrecno = 0; ulong uidrecno = 0;
byte uidhash[20]; byte uidhash[20];
RECNO_LIST recno_list = NULL; /* list of verified records */ 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 ); node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
primary_pk = node->pkt->pkt.public_key; primary_pk = node->pkt->pkt.public_key;
@ -2459,6 +2463,7 @@ update_trust_record( KBNODE keyblock )
case PKT_SIGNATURE: case PKT_SIGNATURE:
if( drec.dirty ) { /* upd_sig_recrod may read the drec */ if( drec.dirty ) { /* upd_sig_recrod may read the drec */
write_record( &drec ); write_record( &drec );
drec.dirty = 0; 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) Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.h (iobuf_get): Now uses .nofast * iobuf.h (iobuf_get): Now uses .nofast

View File

@ -7,6 +7,7 @@ ttyio.h
types.h types.h
util.h util.h
i18n.h i18n.h
host2net.h
g10lib.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_alloc(int usage, size_t bufsize);
IOBUF iobuf_temp(void); IOBUF iobuf_temp(void);
IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
IOBUF iobuf_open( const char *fname ); IOBUF iobuf_open( const char *fname );
IOBUF iobuf_fopen( const char *fname, const char *mode ); IOBUF iobuf_fopen( const char *fname, const char *mode );
IOBUF iobuf_create( const char *fname ); 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_where(a) "[don't know]"
#define iobuf_id(a) ((a)->no) #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_get_temp_length(a) ( (a)->d.len )
#define iobuf_is_temp(a) ( (a)->usage == 3 ) #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 else
echo echo
echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM." 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" DIE="yes"
fi fi
if (automake --version) < /dev/null > /dev/null 2>&1 ; then if (automake --version) < /dev/null > /dev/null 2>&1 ; then
if (aclocal --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 else
echo echo
echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\' echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\'
echo " installed doesn't appear recent enough." echo " installed doesn't appear recent enough."
DIE="yes" DIE="yes"
fi fi
else else
echo echo
echo "**Error**: You must have "\`automake\'" installed to compile $PGM." echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
@ -40,3 +46,5 @@ automake --gnu;
autoheader autoheader
autoconf autoconf
echo "Ready to run ./configure"

View File

@ -1,8 +1,8 @@
## Process this file with automake to produce Makefile.in ## 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 \ 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 noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest
@ -15,10 +15,10 @@ mk_tdata_SOURCES = mk-tdata.c
shmtest_SOURCES = shmtest.c shmtest_SOURCES = shmtest.c
mpicalc_LDADD = @INTLLIBS@ $(needed_libs) mpicalc_LDADD = $(needed_libs)
bftest_LDADD = @INTLLIBS@ $(needed_libs) bftest_LDADD = $(needed_libs)
shmtest_LDADD = @INTLLIBS@ $(needed_libs) shmtest_LDADD = $(needed_libs)
mpicalc bftest shmtest: $(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) Tue Oct 13 12:40:13 1998 Werner Koch (wk@isil.d.shuttle.de)
* util.c (.nofast): set this variable * util.c (.nofast): set this variable

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## 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 noinst_LIBRARIES = libutil.a

View File

@ -483,6 +483,18 @@ iobuf_temp()
return a; 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 * Create a head iobuf for reading from a file
@ -877,8 +889,19 @@ iobuf_flush(IOBUF a)
return 0; return 0;
/*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/ /*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
if( a->usage == 3 ) if( a->usage == 3 ) { /* must increase the size of the temp buffer */
log_bug("temp buffer too short\n"); 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 ) else if( a->usage != 2 )
log_bug("flush on non-output iobuf\n"); log_bug("flush on non-output iobuf\n");
else if( !a->filter ) else if( !a->filter )

View File

@ -161,7 +161,7 @@ g10_log_bug( const char *fmt, ... )
va_list arg_ptr ; va_list arg_ptr ;
putc('\n', stderr ); putc('\n', stderr );
print_prefix("Ooops: "); print_prefix("Ohhhh jeeee: ");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -174,7 +174,7 @@ g10_log_bug( const char *fmt, ... )
void void
g10_log_bug0( const char *file, int line, const char *func ) 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 #else
void void