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

last local commit

This commit is contained in:
Werner Koch 1998-10-16 16:00:17 +00:00
parent 8477407e79
commit e81e0970f7
49 changed files with 1253 additions and 545 deletions

View File

@ -1,3 +1,8 @@
Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* configure.in (NAME_OF_DEV_RANDOM): New.
(DYNLINK_MOD_CFLAGS): New.
Thu Oct 8 10:55:15 1998 Werner Koch (wk@isil.d.shuttle.de) Thu Oct 8 10:55:15 1998 Werner Koch (wk@isil.d.shuttle.de)
* Makefile.am (g10defs.h): creates include file * Makefile.am (g10defs.h): creates include file

19
NEWS
View File

@ -2,6 +2,25 @@ Noteworthy changes in version 0.4.2
----------------------------------- -----------------------------------
* Fixed this huge memory leak. * Fixed this huge memory leak.
* Redesigned the trust database: You should run "gpgm --check-trustdb".
New command --update-trustdb, which adds new key from the public
keyring into your trustdb
* Fixed a bug in the armor code, leading to invalid packet errors.
(a workaround for this was to use --no-armor).
* comment packets are not anymore generated. "--export" filters
them out. One Exception: The comment packets in a secret keyring
are still used because they carry the factorization of the public
prime product.
* --import now only looks for KEYBLOCK headers, so you can now simply
remove the "- " in front of such a header if someone accdently signed
such a message or the keyblock is part of a cleartext signed message.
* --with-colons now lists the key expiration time and not anymore
the valid period.
Noteworthy changes in version 0.4.1 Noteworthy changes in version 0.4.1
----------------------------------- -----------------------------------

24
README
View File

@ -1,4 +1,4 @@
GNUPG - The GNU Privacy Guard GnuPG - The GNU Privacy Guard
------------------------------- -------------------------------
Version 0.4 Version 0.4
@ -8,12 +8,12 @@
On a Linux box (version 2.x.x, alpha or x86 CPU) it should On a Linux box (version 2.x.x, alpha or x86 CPU) it should
work reliably. You may create your key on such a machine and work reliably. You may create your key on such a machine and
use it. Please verify the tar file; there is a PGP and a GNUPG use it. Please verify the tar file; there is a PGP and a GnuPG
signature available. My PGP 2 key is well known and published in signature available. My PGP 2 key is well known and published in
the "Global Trust Register for 1998", ISBN 0-9532397-0-5. the "Global Trust Register for 1998", ISBN 0-9532397-0-5.
I have included my pubring as "g10/pubring.asc", which contains I have included my pubring as "g10/pubring.asc", which contains
the key used to make GNUPG signatures: the key used to make GnuPG signatures:
"pub 1024D/57548DCD 1998-07-07 Werner Koch (gnupg sig) <dd9jn@gnu.org>" "pub 1024D/57548DCD 1998-07-07 Werner Koch (gnupg sig) <dd9jn@gnu.org>"
"Key fingerprint = 6BD9 050F D8FC 941B 4341 2DCC 68B7 AB89 5754 8DCD" "Key fingerprint = 6BD9 050F D8FC 941B 4341 2DCC 68B7 AB89 5754 8DCD"
@ -25,7 +25,7 @@
"pub 1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>" "pub 1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>"
"Key fingerprint = ECAF 7590 EB34 43B5 C7CF 3ACB 6C7E E1B8 621C C013" "Key fingerprint = ECAF 7590 EB34 43B5 C7CF 3ACB 6C7E E1B8 621C C013"
You may add it to your GNUPG pubring and use it in the future to You may add it to your GnuPG pubring and use it in the future to
verify new releases. Because you verified this README file and verify new releases. Because you verified this README file and
_checked_that_it_is_really_my PGP2 key 0C9857A5, you can be sure _checked_that_it_is_really_my PGP2 key 0C9857A5, you can be sure
that the above fingerprints are correct. that the above fingerprints are correct.
@ -36,17 +36,17 @@
See the file COPYING for copyright and warranty information. See the file COPYING for copyright and warranty information.
Due to the fact that GNUPG does not use use any patented algorithm, Due to the fact that GnuPG does not use use any patented algorithm,
it cannot be compatible with old PGP versions, because those use it cannot be compatible with old PGP versions, because those use
IDEA (which is patented worldwide) and RSA (which is patented in IDEA (which is patented worldwide) and RSA (which is patented in
the United States until Sep 20, 2000). the United States until Sep 20, 2000).
GNUPG is in almost all aspects compatible with other OpenPGP GnuPG is in almost all aspects compatible with other OpenPGP
implementations. implementations.
The default algorithms are now DSA and ELGamal. ELGamal for signing The default algorithms are now DSA and ELGamal. ELGamal for signing
is still available, but due to the larger size of such signatures it is still available, but due to the larger size of such signatures it
is depreciated (Please note that the GNUPG implementation of ElGamal is depreciated (Please note that the GnuPG implementation of ElGamal
signatures is *not* insecure). Symmetric algorithms are: 3DES, Blowfish signatures is *not* insecure). Symmetric algorithms are: 3DES, Blowfish
and CAST5, Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192. and CAST5, Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
@ -230,7 +230,7 @@
"#34" "#34"
This can be used by a MUA to specify an exact key after selecting This can be used by a MUA to specify an exact key after selecting
a key from GNUPG (by the use of a special option or an extra utility) a key from GnuPG (by the use of a special option or an extra utility)
* Or by the usual substring: * Or by the usual substring:
@ -245,19 +245,19 @@
Batch mode Batch mode
---------- ----------
If you use the option "--batch", GNUPG runs in non-interactive mode and If you use the option "--batch", GnuPG runs in non-interactive mode and
never prompts for input data. This does not even allow entering the never prompts for input data. This does not even allow entering the
passphrase; until we have a better solution (something like ssh-agent), passphrase; until we have a better solution (something like ssh-agent),
you can use the option "--passhrase-fd n", which works like PGPs you can use the option "--passhrase-fd n", which works like PGPs
PGPPASSFD. PGPPASSFD.
Batch mode also causes GNUPG to terminate as soon as a BAD signature is Batch mode also causes GnuPG to terminate as soon as a BAD signature is
detected. detected.
Exit status Exit status
----------- -----------
GNUPG returns with an exit status of 1 if in batch mode and a bad signature GnuPG returns with an exit status of 1 if in batch mode and a bad signature
has been detected or 2 or higher for all other errors. You should parse has been detected or 2 or higher for all other errors. You should parse
stderr or the output of the fd specified with --status-fd to get detailed stderr or the output of the fd specified with --status-fd to get detailed
information about the errors. information about the errors.
@ -269,7 +269,7 @@
gpg --list-packets datafile gpg --list-packets datafile
Use this to list the contents of a data file. If the file is encrypted Use this to list the contents of a data file. If the file is encrypted
you are asked for the passphrase, so that GNUPG is able to look at the you are asked for the passphrase, so that GnuPG is able to look at the
inner structure of a encrypted packet. inner structure of a encrypted packet.
gpgm --list-trustdb gpgm --list-trustdb

2
THANKS
View File

@ -26,12 +26,14 @@ Jean-loup Gailly gzip@prep.ai.mit.edu
Jens Bachem bachem@rrz.uni-koeln.de Jens Bachem bachem@rrz.uni-koeln.de
John A. Martin jam@jamux.com John A. Martin jam@jamux.com
Jörg Schilling schilling@fokus.gmd.de Jörg Schilling schilling@fokus.gmd.de
Jun Kuriyama kuriyama@sky.rim.or.jp
Karl Fogel kfogel@guanabana.onshore.com Karl Fogel kfogel@guanabana.onshore.com
Karsten Thygesen karthy@kom.auc.dk Karsten Thygesen karthy@kom.auc.dk
Kazu Yamamoto kazu@iijlab.net Kazu Yamamoto kazu@iijlab.net
Lars Kellogg-Stedman lars@bu.edu Lars Kellogg-Stedman lars@bu.edu
Marco d'Itri md@linux.it Marco d'Itri md@linux.it
Mark Adler madler@alumni.caltech.edu Mark Adler madler@alumni.caltech.edu
Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
Martin Schulte schulte@thp.uni-koeln.de Martin Schulte schulte@thp.uni-koeln.de
Matthew Skala mskala@ansuz.sooke.bc.ca Matthew Skala mskala@ansuz.sooke.bc.ca
Max Valianskiy maxcom@maxcom.ml.org Max Valianskiy maxcom@maxcom.ml.org

57
TODO
View File

@ -1,30 +1,41 @@
* change ringedit:
- avoid all copy operations
- delete for update by changing the packet type to a
special unused packet. (export most know about this)
- do an append instead of an update or insert
- export may be used to compress a keyring.
- keep track of all offset in the trustbd and index them
by keyid.
- If the lookup does not find a public key block at the
stored offset disable this keyid.
- If the keyid was not found or is disabled, walk thru
the pubring.
- use ftruncate to recover from keyring errors.
maybe a new option to do this or simply mark the
wrong part as unused.
This makes signature checks and imports much faster; only keys
given by a userid or a fingerprint (RSA only) have to walk tru
the ring.
* There is a new memory leak in update-trustdb
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
OpenBSD binaries are a.out, so every symbol begins with "_"
* use dld if we don't have dlopen.
* should we flush the getkey.c caches while doing an import?
* prefer a type 16 subkey for encryption because pgp cannot handle
type 20.
* calculation of marginals never yields a completely trusted key. * calculation of marginals never yields a completely trusted key.
* list-keys: change valid-days to key expiration date
* disable comments but those in secret keyrings.
* abgelaufene secret keys verhinder ein korrektes initialisieren der
Trustdb.
* import should skip all ascii armored messages headers which are
not keys (some folks are mailing signed public keyblocks :-)
* The critical bit of signature subpackets is not yet supported; i.e. * The critical bit of signature subpackets is not yet supported; i.e.
it is ignored. it is ignored.
* Read more records at once in tdbio.c and provide a lazy write cache.
* Exportable Certification Flag is ignored * Exportable Certification Flag is ignored
* Why does OpenPGP say: The algorithm byte is included in the
checksum of an encoded key, but the actual implementaion does
not do this but works - According to Hal Finney, this is a bug
in the specs.
* fix armor problems (see mails by Brian Moore).
* write a tool to extract selected keys from a file. * write a tool to extract selected keys from a file.
* new menu to delete signatures and list signature in menu * new menu to delete signatures and list signature in menu
@ -33,10 +44,6 @@
* -rdynamic auf Solaris Problem * -rdynamic auf Solaris Problem
* if --libdir is used, the extensions are put in a wrong place.
How does GNOME handle this or make a new option for this directory.
Hmmm, I don´ like to pass ot as a commandline option to cc.
* Replace the SIGUSR1 stuff by semaphores to avoid loss of a signal. * Replace the SIGUSR1 stuff by semaphores to avoid loss of a signal.
* add test cases for invalid data (scrambled armor or other random data) * add test cases for invalid data (scrambled armor or other random data)
@ -61,8 +68,8 @@
can also hold the localid and extend the localid to hold information can also hold the localid and extend the localid to hold information
of the subkey number because two subkeys may have the same keyid. of the subkey number because two subkeys may have the same keyid.
* add an option to re-create a public key from a secret key. Think about * add an option to re-create a public key from a secret key; we
a backup system of only the secret part of the secret key. can do this in trustdb.c:verify_own_keys.
* OpenBSD has sometimes problems reading from /dev/random. * OpenBSD has sometimes problems reading from /dev/random.

View File

@ -71,6 +71,9 @@
#undef USE_RAND_W32 #undef USE_RAND_W32
/* defined if we have a /dev/random and /dev/urandom */ /* defined if we have a /dev/random and /dev/urandom */
#undef HAVE_DEV_RANDOM #undef HAVE_DEV_RANDOM
/* and the real names of the random devices */
#undef NAME_OF_DEV_RANDOM
#undef NAME_OF_DEV_URANDOM
#undef USE_DYNAMIC_LINKING #undef USE_DYNAMIC_LINKING
#undef HAVE_DL_DLOPEN #undef HAVE_DL_DLOPEN

View File

@ -1,3 +1,11 @@
Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
* dynload.c: Support for DLD
Wed Oct 14 12:13:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-unix.c: Now uses names from configure for /dev/random.
1998-10-10 SL Baur <steve@altair.xemacs.org> 1998-10-10 SL Baur <steve@altair.xemacs.org>
* Makefile.am: fix sed -O substitutions to catch -O6, etc. * Makefile.am: fix sed -O substitutions to catch -O6, etc.

View File

@ -11,6 +11,8 @@ else
pkglib_PROGRAMS = pkglib_PROGRAMS =
endif endif
DYNLINK_MOD_CFLAGS = @DYNLINK_MOD_CFLAGS@
libcipher_a_SOURCES = cipher.c \ libcipher_a_SOURCES = cipher.c \
pubkey.c \ pubkey.c \
@ -48,11 +50,11 @@ EXTRA_twofish_SOURCES = twofish.c
tiger: $(srcdir)/tiger.c tiger: $(srcdir)/tiger.c
`echo $(COMPILE) -shared -fPIC -lc -o tiger $(srcdir)/tiger.c | \ `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
sed -e 's/-O[2-9]*/-O1/' ` sed -e 's/-O[2-9]*/-O1/' `
twofish: $(srcdir)/twofish.c twofish: $(srcdir)/twofish.c
`echo $(COMPILE) -shared -fPIC -lc -o twofish $(srcdir)/twofish.c | \ `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \
sed -e 's/-O[0-9]*/ /' ` sed -e 's/-O[0-9]*/ /' `

View File

@ -25,6 +25,8 @@
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_DL_DLOPEN #ifdef HAVE_DL_DLOPEN
#include <dlfcn.h> #include <dlfcn.h>
#elif defined(HAVE_DLD_DLD_LINK)
#include <dld.h>
#endif #endif
#include "util.h" #include "util.h"
#include "cipher.h" #include "cipher.h"
@ -37,7 +39,11 @@
typedef struct ext_list { typedef struct ext_list {
struct ext_list *next; struct ext_list *next;
#ifdef HAVE_DL_DLOPEN
void *handle; /* handle from dlopen() */ void *handle; /* handle from dlopen() */
#else
int handle; /* if the function has been loaded, this is true */
#endif
int failed; /* already tried but failed */ int failed; /* already tried but failed */
void * (*enumfunc)(int, int*, int*, int*); void * (*enumfunc)(int, int*, int*, int*);
char *hintstr; /* pointer into name */ char *hintstr; /* pointer into name */
@ -53,6 +59,14 @@ typedef struct {
void *sym; void *sym;
} ENUMCONTEXT; } ENUMCONTEXT;
#ifdef HAVE_DLD_DLD_LINK
static char *mainpgm_path;
static int did_dld_init;
static int dld_available;
#endif
/**************** /****************
* Register an extension module. The last registered module will * Register an extension module. The last registered module will
* be loaded first. A name may have a list of classes * be loaded first. A name may have a list of classes
@ -62,13 +76,20 @@ typedef struct {
* algorithms 20 and 109. This is only a hint but if it is there the * algorithms 20 and 109. This is only a hint but if it is there the
* loader may decide to only load a module which claims to have a * loader may decide to only load a module which claims to have a
* requested algorithm. * requested algorithm.
*
* mainpgm is the path to the program which wants to load a module
* it is only used in some environments.
*/ */
void void
register_cipher_extension( const char *fname ) register_cipher_extension( const char *mainpgm, const char *fname )
{ {
EXTLIST r, el; EXTLIST r, el;
char *p, *pe; char *p, *pe;
#ifdef HAVE_DLD_DLD_LINK
if( !mainpgm_path && mainpgm && *mainpgm )
mainpgm_path = m_strdup(mainpgm);
#endif
if( *fname != '/' ) { /* do tilde expansion etc */ if( *fname != '/' ) { /* do tilde expansion etc */
char *p ; char *p ;
@ -110,16 +131,22 @@ load_extension( EXTLIST el )
{ {
#ifdef USE_DYNAMIC_LINKING #ifdef USE_DYNAMIC_LINKING
char **name; char **name;
void *sym; #ifdef HAVE_DL_DLOPEN
const char *err; const char *err;
int seq = 0; int seq = 0;
int class, vers; int class, vers;
void *sym;
#else
unsigned long addr;
int rc;
#endif
/* make sure we are not setuid */ /* make sure we are not setuid */
if( getuid() != geteuid() ) if( getuid() != geteuid() )
log_bug("trying to load an extension while still setuid\n"); log_bug("trying to load an extension while still setuid\n");
/* now that we are not setuid anymore, we can safely load modules */ /* now that we are not setuid anymore, we can safely load modules */
#ifdef HAVE_DL_DLOPEN
el->handle = dlopen(el->name, RTLD_NOW); el->handle = dlopen(el->name, RTLD_NOW);
if( !el->handle ) { if( !el->handle ) {
log_error("%s: error loading extension: %s\n", el->name, dlerror() ); log_error("%s: error loading extension: %s\n", el->name, dlerror() );
@ -130,6 +157,38 @@ load_extension( EXTLIST el )
log_error("%s: not a gnupg extension: %s\n", el->name, err ); log_error("%s: not a gnupg extension: %s\n", el->name, err );
goto failure; goto failure;
} }
#else /* have dld */
if( !did_dld_init ) {
did_dld_init = 1;
if( !mainpgm_path )
log_error("DLD is not correctly initialized\n");
else {
rc = dld_init( dld_find_executable(mainpgm_path) );
if( rc )
log_error("DLD init failed: %s\n", dld_strerror(rc) );
else
dld_available = 1;
}
}
if( !dld_available ) {
log_error("%s: DLD not available\n", el->name );
goto failure;
}
rc = dld_link( el->name );
if( rc ) {
log_error("%s: error loading extension: %s\n",
el->name, dld_strerror(rc) );
goto failure;
}
addr = dld_get_symbol("gnupgext_version");
if( !addr ) {
log_error("%s: not a gnupg extension: %s\n",
el->name, dld_strerror(dld_errno) );
goto failure;
}
name = (char**)addr;
#endif
if( g10_opt_verbose ) if( g10_opt_verbose )
log_info("%s: %s%s%s%s\n", el->name, *name, log_info("%s: %s%s%s%s\n", el->name, *name,
@ -137,13 +196,31 @@ load_extension( EXTLIST el )
el->hintstr? el->hintstr:"", el->hintstr? el->hintstr:"",
el->hintstr? ")":""); el->hintstr? ")":"");
#ifdef HAVE_DL_DLOPEN
sym = dlsym(el->handle, "gnupgext_enum_func"); sym = dlsym(el->handle, "gnupgext_enum_func");
if( (err=dlerror()) ) { if( (err=dlerror()) ) {
log_error("%s: invalid gnupg extension: %s\n", el->name, err ); log_error("%s: invalid gnupg extension: %s\n", el->name, err );
goto failure; goto failure;
} }
el->enumfunc = (void *(*)(int,int*,int*,int*))sym; el->enumfunc = (void *(*)(int,int*,int*,int*))sym;
#else /* dld */
addr = dld_get_func("gnupgext_enum_func");
if( !addr ) {
log_error("%s: invalid gnupg extension: %s\n",
el->name, dld_strerror(dld_errno) );
goto failure;
}
rc = dld_function_executable_p("gnupgext_enum_func");
if( rc ) {
log_error("%s: extension function is not executable: %s\n",
el->name, dld_strerror(rc) );
goto failure;
}
el->enumfunc = (void *(*)(int,int*,int*,int*))addr;
el->handle = 1; /* mark as usable */
#endif
#ifdef HAVE_DL_DLOPEN
if( g10_opt_verbose > 1 ) { if( g10_opt_verbose > 1 ) {
/* list the contents of the module */ /* list the contents of the module */
while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) { while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) {
@ -166,13 +243,16 @@ load_extension( EXTLIST el )
} }
} }
} }
#endif
return 0; return 0;
failure: failure:
#ifdef HAVE_DL_DLOPEN
if( el->handle ) { if( el->handle ) {
dlclose(el->handle); dlclose(el->handle);
el->handle = NULL; el->handle = NULL;
} }
#endif
el->failed = 1; el->failed = 1;
#endif /*USE_DYNAMIC_LINKING*/ #endif /*USE_DYNAMIC_LINKING*/
return -1; return -1;

View File

@ -89,10 +89,10 @@ fast_random_poll()
} }
#ifdef HAVE_DEV_RANDOM /* we have the /dev/random device */ #ifdef HAVE_DEV_RANDOM /* we have the /dev/random devices */
/**************** /****************
* Used to open the Linux /dev/random device * Used to open the Linux and xBSD /dev/random devices
*/ */
static int static int
open_device( const char *name, int minor ) open_device( const char *name, int minor )
@ -126,12 +126,12 @@ read_random_source( byte *buffer, size_t length, int level )
if( level >= 2 ) { if( level >= 2 ) {
if( fd_random == -1 ) if( fd_random == -1 )
fd_random = open_device( "/dev/random", 8 ); fd_random = open_device( NAME_OF_DEV_RANDOM, 8 );
fd = fd_random; fd = fd_random;
} }
else { else {
if( fd_urandom == -1 ) if( fd_urandom == -1 )
fd_urandom = open_device( "/dev/urandom", 9 ); fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 );
fd = fd_urandom; fd = fd_urandom;
} }
do { do {

View File

@ -76,6 +76,7 @@ AC_PROG_INSTALL
AM_CYGWIN32 AM_CYGWIN32
case "${target}" in case "${target}" in
i386--mingw32) i386--mingw32)
# special stuff for Windoze NT # special stuff for Windoze NT
@ -104,6 +105,23 @@ case "${target}" in
esac esac
AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME") AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME")
dnl Fixme: Are these the best flags for OpenBSD????
case "${target}" in
*-openbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -Wl,-Bshareable -Wl,-x"
;;
*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -fPIC -lc"
;;
esac
AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM")
AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
dnl Checks for libraries. dnl Checks for libraries.
@ -126,12 +144,15 @@ fi
else else
AC_MSG_CHECKING(for dynamic loading) AC_MSG_CHECKING(for dynamic loading)
DYNLINK_LDFLAGS= DYNLINK_LDFLAGS=
DYNLINK_MOD_CFLAGS=
use_gnupg_extensions=no use_gnupg_extensions=no
AC_MSG_RESULT(has been disabled) AC_MSG_RESULT(has been disabled)
fi fi
AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes ) AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes )
AC_SUBST(DYNLINK_LDFLAGS) AC_SUBST(DYNLINK_LDFLAGS)
AC_SUBST(DYNLINK_MOD_CFLAGS)
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
@ -182,7 +203,7 @@ fi
dnl check whether we have a random device dnl check whether we have a random device
if test "$try_dev_random" = yes ; then if test "$try_dev_random" = yes ; then
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random, AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
[if test -c /dev/random && test -c /dev/urandom ; then [if test -c "$NAME_OF_DEV_RANDOM" && test -c "$NAME_OF_DEV_URANDOM" ; then
ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi]) ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
if test "$ac_cv_have_dev_random" = yes; then if test "$ac_cv_have_dev_random" = yes; then
AC_DEFINE(HAVE_DEV_RANDOM) AC_DEFINE(HAVE_DEV_RANDOM)
@ -194,8 +215,6 @@ else
fi fi
dnl setup assembler stuff dnl setup assembler stuff
AC_MSG_CHECKING(for mpi assembler functions) AC_MSG_CHECKING(for mpi assembler functions)
if test -f $srcdir/mpi/config.links ; then if test -f $srcdir/mpi/config.links ; then

View File

@ -22,8 +22,7 @@ ssb::1536:20:5CE086B5B5A18FF4:1998-07-07:0:::
20 = ElGamal (sign and encrypt) 20 = ElGamal (sign and encrypt)
5. Field: KeyID 5. Field: KeyID
6. Field: Creation Date (in UTC) 6. Field: Creation Date (in UTC)
7. Field: key expieres n days after creation. 7. Field: Key expiration date or empty if none.
(I will change this to a key exiration date)
8. Field: Local ID: record number of the dir record in the trustdb 8. Field: Local ID: record number of the dir record in the trustdb
this value is only valid as long as the trustdb is not this value is only valid as long as the trustdb is not
deleted. May be later used to lookup the key: You will be deleted. May be later used to lookup the key: You will be

View File

@ -1,6 +1,35 @@
Fri Oct 16 10:24:47 1998 Werner Koch (wk@isil.d.shuttle.de)
* trustdb.c: Rewrote most.
* tdbio.c: Add cache and generalized hash tables.
* options.h (ENABLE_COMMENT_PACKETS): New but undef'ed.
* encode.c, sign.c, keygen.c: Disabled comment packets.
* export.c (do_export): Comment packets are never exported,
except for those in the secret keyring.
* g10.c (main): Removed option do-no-export-rsa; should be
be replaced by a secpial tool.
* export.c (do_export): Removed the code for the above option.
* armor.c (find_header): Support for new only_keyblocks.
* import.c (import_keys): Only looks for keyblock armors.
* packet.h: replaced valid_days by expiredate and changed all users.
* build-packet.c (do_public_key): calculates valid-days
(do_secret_key): Ditto.
* parse-packet.c (parse_key): expiredate is calucated from the
valid_period in v3 packets.
* keyid.c (do_fingerprint_md): calculates valid_dates.
* keygen.c (add_key_expire): fixed key expiration time for v4 packets.
* armor.c (find_header): A LF in the first 28 bytes
was skipped for non-armored data.
Thu Oct 8 11:35:51 1998 Werner Koch (wk@isil.d.shuttle.de) Thu Oct 8 11:35:51 1998 Werner Koch (wk@isil.d.shuttle.de)
* armor.c (is_armored): Ad test on old comment packets. * armor.c (is_armored): Add test on old comment packets.
* tdbio.c (tdbio_search_dir_bypk): fixed memory leak. * tdbio.c (tdbio_search_dir_bypk): fixed memory leak.

View File

@ -109,7 +109,8 @@ static char *tail_strings[] = {
static fhdr_state_t find_header( fhdr_state_t state, static fhdr_state_t find_header( fhdr_state_t state,
byte *buf, size_t *r_buflen, byte *buf, size_t *r_buflen,
IOBUF a, size_t n, IOBUF a, size_t n,
unsigned *r_empty, int *r_hashes ); unsigned *r_empty, int *r_hashes,
int only_keyblocks );
static void static void
@ -260,7 +261,8 @@ parse_hash_header( const char *line )
*/ */
static fhdr_state_t static fhdr_state_t
find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
IOBUF a, size_t n, unsigned *r_empty, int *r_hashes ) IOBUF a, size_t n, unsigned *r_empty, int *r_hashes,
int only_keyblocks )
{ {
int c=0, i; int c=0, i;
const char *s; const char *s;
@ -273,7 +275,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
buflen = *r_buflen; buflen = *r_buflen;
assert(buflen >= 100 ); assert(buflen >= 100 );
buflen -= 3; /* reserved room for CR,LF and one extra */ buflen -= 4; /* reserved room for CR,LF, and two extra */
do { do {
switch( state ) { switch( state ) {
@ -281,14 +283,17 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
/* read at least the first byte to check whether it is armored /* read at least the first byte to check whether it is armored
* or not */ * or not */
c = 0; c = 0;
for(n=0; n < 28 && (c=iobuf_get2(a)) != -1 && c != '\n'; ) for(n=0; n < 28 && (c=iobuf_get(a)) != -1 && c != '\n'; )
buf[n++] = c; buf[n++] = c;
if( !n && c == '\n' ) if( !n && c == '\n' )
state = fhdrCHECKBegin; state = fhdrCHECKBegin;
else if( !n || c == -1 ) else if( !n || c == -1 )
state = fhdrNOArmor; /* too short */ state = fhdrNOArmor; /* too short */
else if( !is_armored( buf ) ) else if( !is_armored( buf ) ) {
state = fhdrNOArmor; state = fhdrNOArmor;
if( c == '\n' )
buf[n++] = c;
}
else if( c == '\n' ) else if( c == '\n' )
state = fhdrCHECKBegin; state = fhdrCHECKBegin;
else else
@ -299,7 +304,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
n = 0; n = 0;
case fhdrINITCont: /* read more stuff into buffer */ case fhdrINITCont: /* read more stuff into buffer */
c = 0; c = 0;
for(; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) for(; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
buf[n++] = c; buf[n++] = c;
state = c == '\n' ? fhdrCHECKBegin : state = c == '\n' ? fhdrCHECKBegin :
c == -1 ? fhdrEOF : fhdrINITSkip; c == -1 ? fhdrEOF : fhdrINITSkip;
@ -309,21 +314,21 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
if( c == '\n' ) if( c == '\n' )
n = 0; n = 0;
else { else {
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) while( (c=iobuf_get(a)) != -1 && c != '\n' )
; ;
} }
state = c == -1? fhdrEOF : fhdrINIT; state = c == -1? fhdrEOF : fhdrINIT;
break; break;
case fhdrSKIPHeader: case fhdrSKIPHeader:
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) while( (c=iobuf_get(a)) != -1 && c != '\n' )
; ;
state = c == -1? fhdrEOF : fhdrWAITHeader; state = c == -1? fhdrEOF : fhdrWAITHeader;
break; break;
case fhdrWAITHeader: /* wait for Header lines */ case fhdrWAITHeader: /* wait for Header lines */
c = 0; c = 0;
for(n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) for(n=0; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
buf[n++] = c; buf[n++] = c;
buf[n] = 0; buf[n] = 0;
if( n < buflen || c == '\n' ) { if( n < buflen || c == '\n' ) {
@ -388,7 +393,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
case fhdrWAITClearsig: /* skip the empty line (for clearsig) */ case fhdrWAITClearsig: /* skip the empty line (for clearsig) */
c = 0; c = 0;
for(n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) for(n=0; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
buf[n++] = c; buf[n++] = c;
if( n < buflen || c == '\n' ) { if( n < buflen || c == '\n' ) {
buf[n] = 0; buf[n] = 0;
@ -432,6 +437,9 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
break; break;
if( !s ) if( !s )
break; /* unknown begin line */ break; /* unknown begin line */
if( only_keyblocks && i != 1 && i != 5 && i != 6 )
break; /* not a keyblock armor */
/* found the begin line */ /* found the begin line */
hdr_line = i; hdr_line = i;
state = fhdrWAITHeader; state = fhdrWAITHeader;
@ -448,7 +456,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
* we have to look for a header line or dashed escaped text*/ * we have to look for a header line or dashed escaped text*/
n = 0; n = 0;
c = 0; c = 0;
while( n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n' ) while( n < buflen && (c=iobuf_get(a)) != -1 && c != '\n' )
buf[n++] = c; buf[n++] = c;
buf[n] = 0; buf[n] = 0;
if( c == -1 ) if( c == -1 )
@ -516,7 +524,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
* for dashed escaped text of headers */ * for dashed escaped text of headers */
c = 0; c = 0;
n = 0; n = 0;
while( n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n' ) while( n < buflen && (c=iobuf_get(a)) != -1 && c != '\n' )
buf[n++] = c; buf[n++] = c;
buf[n] = 0; buf[n] = 0;
if( c == -1 ) if( c == -1 )
@ -534,7 +542,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
* counting spaces is not enough, because it may be a * counting spaces is not enough, because it may be a
* mix of different white space characters */ * mix of different white space characters */
IOBUF b = iobuf_temp(); IOBUF b = iobuf_temp();
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) { while( (c=iobuf_get(a)) != -1 && c != '\n' ) {
iobuf_put(b,c); iobuf_put(b,c);
if( c != ' ' && c != '\t' && c != '\r' ) if( c != ' ' && c != '\t' && c != '\r' )
break; break;
@ -622,7 +630,8 @@ check_input( armor_filter_context_t *afx, IOBUF a )
n = DIM(afx->helpbuf); n = DIM(afx->helpbuf);
state = find_header( state, afx->helpbuf, &n, a, state = find_header( state, afx->helpbuf, &n, a,
afx->helplen, &emplines, &afx->hashes); afx->helplen, &emplines, &afx->hashes,
afx->only_keyblocks );
switch( state ) { switch( state ) {
case fhdrNOArmor: case fhdrNOArmor:
afx->inp_checked = 1; afx->inp_checked = 1;
@ -708,7 +717,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
afx->helpidx = 0; afx->helpidx = 0;
state = find_header( state, afx->helpbuf, &n, a, state = find_header( state, afx->helpbuf, &n, a,
state == fhdrNullClearsig? afx->helplen:0, state == fhdrNullClearsig? afx->helplen:0,
&emplines, &afx->hashes ); &emplines, &afx->hashes,
afx->only_keyblocks );
switch( state) { switch( state) {
case fhdrERROR: case fhdrERROR:
invalid_armor(); invalid_armor();

View File

@ -209,8 +209,14 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
else else
iobuf_put( a, pk->version ); iobuf_put( a, pk->version );
write_32(a, pk->timestamp ); write_32(a, pk->timestamp );
if( pk->version < 4 ) if( pk->version < 4 ) {
write_16(a, pk->valid_days ); u16 ndays;
if( pk->expiredate )
ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
else
ndays = 0;
write_16(a, 0 );
}
iobuf_put(a, pk->pubkey_algo ); iobuf_put(a, pk->pubkey_algo );
n = pubkey_get_npkey( pk->pubkey_algo ); n = pubkey_get_npkey( pk->pubkey_algo );
if( !n ) if( !n )
@ -280,8 +286,14 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
else else
iobuf_put( a, sk->version ); iobuf_put( a, sk->version );
write_32(a, sk->timestamp ); write_32(a, sk->timestamp );
if( sk->version < 4 ) if( sk->version < 4 ) {
write_16(a, sk->valid_days ); u16 ndays;
if( sk->expiredate )
ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
else
ndays = 0;
write_16(a, 0 );
}
iobuf_put(a, sk->pubkey_algo ); iobuf_put(a, sk->pubkey_algo );
nskey = pubkey_get_nskey( sk->pubkey_algo ); nskey = pubkey_get_nskey( sk->pubkey_algo );
npkey = pubkey_get_npkey( sk->pubkey_algo ); npkey = pubkey_get_npkey( sk->pubkey_algo );

View File

@ -118,12 +118,14 @@ encode_simple( const char *filename, int mode )
if( opt.armor ) if( opt.armor )
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
#ifdef ENABLE_COMMENT_PACKETS
else { else {
write_comment( out, "#created by GNUPG v" VERSION " (" write_comment( out, "#created by GNUPG v" VERSION " ("
PRINTABLE_OS_NAME ")"); PRINTABLE_OS_NAME ")");
if( opt.comment_string ) if( opt.comment_string )
write_comment( out, opt.comment_string ); write_comment( out, opt.comment_string );
} }
#endif
if( s2k && !opt.rfc1991 ) { if( s2k && !opt.rfc1991 ) {
PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc ); PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc );
enc->version = 4; enc->version = 4;
@ -224,13 +226,14 @@ encode_crypt( const char *filename, STRLIST remusr )
if( opt.armor ) if( opt.armor )
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
#ifdef ENABLE_COMMENT_PACKETS
else { else {
write_comment( out, "#created by GNUPG v" VERSION " (" write_comment( out, "#created by GNUPG v" VERSION " ("
PRINTABLE_OS_NAME ")"); PRINTABLE_OS_NAME ")");
if( opt.comment_string ) if( opt.comment_string )
write_comment( out, opt.comment_string ); write_comment( out, opt.comment_string );
} }
#endif
/* create a session key */ /* create a session key */
cfx.dek = m_alloc_secure( sizeof *cfx.dek ); cfx.dek = m_alloc_secure( sizeof *cfx.dek );
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ if( !opt.def_cipher_algo ) { /* try to get it from the prefs */

View File

@ -124,24 +124,10 @@ do_export( STRLIST users, int secret )
/* and write it */ /* and write it */
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
if( opt.do_not_export_rsa ) { /* don't export any comment packets but those in the
int algo; * secret keyring */
switch( node->pkt->pkttype ) { if( !secret && node->pkt->pkttype == PKT_COMMENT )
/* note: we can´ do this for subkeys here */
case PKT_PUBLIC_KEY:
algo = node->pkt->pkt.public_key->pubkey_algo;
break;
case PKT_SECRET_KEY:
algo = node->pkt->pkt.secret_key->pubkey_algo;
break;
case PKT_SIGNATURE:
algo = node->pkt->pkt.signature->pubkey_algo;
break;
default: algo = 0;
}
if( is_RSA(algo) )
continue; continue;
}
if( (rc = build_packet( out, node->pkt )) ) { if( (rc = build_packet( out, node->pkt )) ) {
log_error("build_packet(%d) failed: %s\n", log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) ); node->pkt->pkttype, g10_errstr(rc) );

View File

@ -31,6 +31,7 @@ typedef struct {
typedef struct { typedef struct {
int status; int status;
int what; int what;
int only_keyblocks; /* skip all headers but ".... key block" */
byte radbuf[4]; byte radbuf[4];
int idx, idx2; int idx, idx2;
u32 crc; u32 crc;

View File

@ -354,7 +354,7 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
if( a->timestamp != b->timestamp ) if( a->timestamp != b->timestamp )
return -1; return -1;
if( a->valid_days != b->valid_days ) if( a->expiredate != b->expiredate )
return -1; return -1;
if( a->pubkey_algo != b->pubkey_algo ) if( a->pubkey_algo != b->pubkey_algo )
return -1; return -1;
@ -380,7 +380,7 @@ cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
if( pk->timestamp != sk->timestamp ) if( pk->timestamp != sk->timestamp )
return -1; return -1;
if( pk->valid_days != sk->valid_days ) if( pk->expiredate != sk->expiredate )
return -1; return -1;
if( pk->pubkey_algo != sk->pubkey_algo ) if( pk->pubkey_algo != sk->pubkey_algo )
return -1; return -1;

View File

@ -1,4 +1,4 @@
/* g10.c - The GNUPG utility (main for gpg) /* g10.c - The GnuPG utility (main for gpg)
* 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.
@ -88,6 +88,7 @@ enum cmd_and_opt_values { aNull = 0,
aPrintMD, aPrintMD,
aPrintMDs, aPrintMDs,
aCheckTrustDB, aCheckTrustDB,
aUpdateTrustDB,
aFixTrustDB, aFixTrustDB,
aListTrustDB, aListTrustDB,
aListTrustPath, aListTrustPath,
@ -98,7 +99,6 @@ enum cmd_and_opt_values { aNull = 0,
aGenRandom, aGenRandom,
oFingerprint, oFingerprint,
oDoNotExportRSA,
oAnswerYes, oAnswerYes,
oAnswerNo, oAnswerNo,
oKeyring, oKeyring,
@ -172,13 +172,17 @@ static ARGPARSE_OPTS opts[] = {
#endif #endif
{ aExport, "export" , 256, N_("export keys") }, { aExport, "export" , 256, N_("export keys") },
{ aExportSecret, "export-secret-keys" , 256, "@" }, { aExportSecret, "export-secret-keys" , 256, "@" },
{ oDoNotExportRSA, "do-not-export-rsa", 0, "@" },
{ aImport, "import", 256 , N_("import/merge keys")}, { aImport, "import", 256 , N_("import/merge keys")},
{ aListPackets, "list-packets",256,N_("list only the sequence of packets")}, { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
#ifdef IS_G10MAINT #ifdef IS_G10MAINT
{ aExportOwnerTrust, "export-ownertrust", 256, N_("export the ownertrust values")}, { aExportOwnerTrust,
{ aImportOwnerTrust, "import-ownertrust", 256 , N_("import ownertrust values")}, "export-ownertrust", 256, N_("export the ownertrust values")},
{ aCheckTrustDB, "check-trustdb",0 , N_("|[NAMES]|check the trust database")}, { aImportOwnerTrust,
"import-ownertrust", 256 , N_("import ownertrust values")},
{ aUpdateTrustDB,
"update-trustdb",0 , N_("|[NAMES]|update the trust database")},
{ aCheckTrustDB,
"check-trustdb",0 , N_("|[NAMES]|check the trust database")},
{ aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")}, { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
{ aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") }, { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
{ aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") }, { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
@ -302,9 +306,9 @@ strusage( int level )
switch( level ) { switch( level ) {
case 11: p = case 11: p =
#ifdef IS_G10MAINT #ifdef IS_G10MAINT
"gpgm (GNUPG)"; "gpgm (GnuPG)";
#else #else
"gpg (GNUPG)"; "gpg (GnuPG)";
#endif #endif
break; break;
case 13: p = VERSION; break; case 13: p = VERSION; break;
@ -323,7 +327,7 @@ strusage( int level )
case 41: p = case 41: p =
#ifdef IS_G10MAINT #ifdef IS_G10MAINT
_("Syntax: gpgm [options] [files]\n" _("Syntax: gpgm [options] [files]\n"
"GNUPG maintenance utility\n"); "GnuPG maintenance utility\n");
#else #else
_("Syntax: gpg [options] [files]\n" _("Syntax: gpg [options] [files]\n"
"sign, check, encrypt or decrypt\n" "sign, check, encrypt or decrypt\n"
@ -638,6 +642,7 @@ main( int argc, char **argv )
case aPrintMDs: set_cmd( &cmd, aPrintMDs); break; case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
case aListTrustDB: set_cmd( &cmd, aListTrustDB); break; case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break; case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break; case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
case aListTrustPath: set_cmd( &cmd, aListTrustPath); break; case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
case aDeArmor: set_cmd( &cmd, aDeArmor); break; case aDeArmor: set_cmd( &cmd, aDeArmor); break;
@ -692,10 +697,12 @@ main( int argc, char **argv )
case oCompressKeys: opt.compress_keys = 1; break; case oCompressKeys: opt.compress_keys = 1; break;
case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break; case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
case oAlwaysTrust: opt.always_trust = 1; break; case oAlwaysTrust: opt.always_trust = 1; break;
case oLoadExtension: register_cipher_extension(pargs.r.ret_str); break; case oLoadExtension:
register_cipher_extension(orig_argc? *orig_argv:NULL,
pargs.r.ret_str);
break;
case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break; case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break;
case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break; case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
case oDoNotExportRSA: opt.do_not_export_rsa = 1; break;
case oCompressSigs: opt.compress_sigs = 1; break; case oCompressSigs: opt.compress_sigs = 1; break;
case oRunAsShmCP: case oRunAsShmCP:
#ifndef USE_SHM_COPROCESSING #ifndef USE_SHM_COPROCESSING
@ -835,13 +842,13 @@ main( int argc, char **argv )
&& !(cmd == aKMode && argc == 2 ) ) { && !(cmd == aKMode && argc == 2 ) ) {
if( !sec_nrings || default_keyring ) /* add default secret rings */ if( !sec_nrings || default_keyring ) /* add default secret rings */
add_secret_keyring("secring.gpg"); add_keyblock_resource("secring.gpg", 0, 1);
for(sl = sec_nrings; sl; sl = sl->next ) for(sl = sec_nrings; sl; sl = sl->next )
add_secret_keyring( sl->d ); add_keyblock_resource( sl->d, 0, 1 );
if( !nrings || default_keyring ) /* add default ring */ if( !nrings || default_keyring ) /* add default ring */
add_keyring("pubring.gpg"); add_keyblock_resource("pubring.gpg", 0, 0);
for(sl = nrings; sl; sl = sl->next ) for(sl = nrings; sl; sl = sl->next )
add_keyring( sl->d ); add_keyblock_resource( sl->d, 0, 0 );
} }
FREE_STRLIST(nrings); FREE_STRLIST(nrings);
FREE_STRLIST(sec_nrings); FREE_STRLIST(sec_nrings);
@ -996,7 +1003,7 @@ main( int argc, char **argv )
else { else {
/* add keyring (default keyrings are not registered in this /* add keyring (default keyrings are not registered in this
* special case */ * special case */
add_keyring( argv[1] ); add_keyblock_resource( argv[1], 0, 0 );
public_key_list( **argv?1:0, argv ); public_key_list( **argv?1:0, argv );
} }
} }
@ -1160,6 +1167,12 @@ main( int argc, char **argv )
} }
break; break;
case aUpdateTrustDB:
if( argc )
wrong_args("--update-trustdb");
update_trustdb();
break;
case aCheckTrustDB: case aCheckTrustDB:
if( !argc ) if( !argc )
check_trustdb(NULL); check_trustdb(NULL);

View File

@ -37,16 +37,15 @@
#define MAX_PK_CACHE_ENTRIES 50 #define MAX_PK_CACHE_ENTRIES 50
#define MAX_UID_CACHE_ENTRIES 50 #define MAX_UID_CACHE_ENTRIES 50
static struct {
typedef struct enum_seckey_context { int any;
int eof; int okay_count;
STRLIST sl; int nokey_count;
IOBUF iobuf; int error_count;
} enum_seckey_context_t; } lkup_stats[21];
static STRLIST keyrings;
static STRLIST secret_keyrings;
#if MAX_UNK_CACHE_ENTRIES #if MAX_UNK_CACHE_ENTRIES
typedef struct keyid_list { typedef struct keyid_list {
@ -89,92 +88,24 @@ static int lookup( PKT_public_key *pk,
static int lookup_sk( PKT_secret_key *sk, static int lookup_sk( PKT_secret_key *sk,
int mode, u32 *keyid, const char *name, int primary ); int mode, u32 *keyid, const char *name, int primary );
/* note this function may be called before secure memory is
* available
* The first keyring which is added by this function is static void
* created if it does not exist. print_stats()
*/
void
add_keyring( const char *name )
{ {
STRLIST sl; int i;
int rc, force = !keyrings; for(i=0; i < DIM(lkup_stats); i++ ) {
if( lkup_stats[i].any )
if( *name != '/' ) { /* do tilde expansion etc */ fprintf(stderr,
char *p ; "lookup stats: mode=%-2d ok=%-6d nokey=%-6d err=%-6d\n",
i,
if( strchr(name, '/') ) lkup_stats[i].okay_count,
p = make_filename(name, NULL); lkup_stats[i].nokey_count,
else lkup_stats[i].error_count );
p = make_filename(opt.homedir, name, NULL);
sl = append_to_strlist( &keyrings, p );
m_free(p);
} }
else
sl = append_to_strlist( &keyrings, name );
/* fixme: We should remove much out of this module and
* combine it with the keyblock stuff from ringedit.c
* For now we will simple add the filename as keyblock resource
*/
rc = add_keyblock_resource( sl->d, force, 0 );
if( rc )
log_error("keyblock resource '%s': %s\n", sl->d, g10_errstr(rc) );
} }
/****************
* Get the name of the keyrings, start with a sequence number of 0.
*/
const char *
get_keyring( int sequence )
{
STRLIST sl;
for(sl = keyrings; sl && sequence; sl = sl->next, sequence-- )
;
return sl? sl->d : NULL;
}
const char *
get_secret_keyring( int sequence )
{
STRLIST sl;
for(sl = secret_keyrings; sl && sequence; sl = sl->next, sequence-- )
;
return sl? sl->d : NULL;
}
void
add_secret_keyring( const char *name )
{
STRLIST sl;
int rc, force = !secret_keyrings;
if( *name != '/' ) { /* do tilde expansion etc */
char *p ;
if( strchr(name, '/') )
p = make_filename(name, NULL);
else
p = make_filename(opt.homedir, name, NULL);
sl = append_to_strlist( &secret_keyrings, p );
m_free(p);
}
else
sl = append_to_strlist( &secret_keyrings, name );
/* fixme: We should remove much out of this module and
* combine it with the keyblock stuff from ringedit.c
* For now we will simple add the filename as keyblock resource
*/
rc = add_keyblock_resource( sl->d, force, 1 );
if( rc )
log_error("secret keyblock resource '%s': %s\n", sl->d, g10_errstr(rc));
}
static void static void
cache_public_key( PKT_public_key *pk ) cache_public_key( PKT_public_key *pk )
@ -690,7 +621,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
*/ */
const byte *p; const byte *p;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL ); p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
pk->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0; pk->expiredate = p? buffer_to_u32(p):0;
/* fixme: add usage etc. to pk */ /* fixme: add usage etc. to pk */
break; break;
} }
@ -739,12 +670,12 @@ merge_keys_and_selfsig( KBNODE keyblock )
const byte *p; const byte *p;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL ); p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
if( pk ) { if( pk ) {
pk->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0; pk->expiredate = p? buffer_to_u32(p):0;
/* fixme: add usage etc. */ /* fixme: add usage etc. */
pk = NULL; /* use only the first self signature */ pk = NULL; /* use only the first self signature */
} }
else { else {
sk->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0; sk->expiredate = p? buffer_to_u32(p):0;
sk = NULL; /* use only the first self signature */ sk = NULL; /* use only the first self signature */
} }
} }
@ -756,7 +687,7 @@ merge_keys_and_selfsig( KBNODE keyblock )
/**************** /****************
* Lookup a key by scanning all keyrings * Lookup a key by scanning all keyresources
* mode 1 = lookup by NAME (exact) * mode 1 = lookup by NAME (exact)
* 2 = lookup by NAME (substring) * 2 = lookup by NAME (substring)
* 3 = lookup by NAME (email address) * 3 = lookup by NAME (email address)
@ -949,6 +880,24 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock ); release_kbnode( keyblock );
set_packet_list_mode(oldmode); set_packet_list_mode(oldmode);
if( opt.debug & DBG_MEMSTAT_VALUE ) {
static int initialized;
if( !initialized ) {
initialized = 1;
atexit( print_stats );
}
assert( mode < DIM(lkup_stats) );
lkup_stats[mode].any = 1;
if( !rc )
lkup_stats[mode].okay_count++;
else if ( rc == G10ERR_NO_PUBKEY )
lkup_stats[mode].nokey_count++;
else
lkup_stats[mode].error_count++;
}
return rc; return rc;
} }
@ -1107,12 +1056,19 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
int rc=0; int rc=0;
PACKET pkt; PACKET pkt;
int save_mode; int save_mode;
enum_seckey_context_t *c = *context; struct {
int eof;
int sequence;
const char *name;
IOBUF iobuf;
} *c = *context;
if( !c ) { /* make a new context */ if( !c ) { /* make a new context */
c = m_alloc_clear( sizeof *c ); c = m_alloc_clear( sizeof *c );
*context = c; *context = c;
c->sl = secret_keyrings; c->sequence = 0;
c->name = enum_keyblock_resources( &c->sequence, 1 );
} }
if( !sk ) { /* free the context */ if( !sk ) { /* free the context */
@ -1126,10 +1082,11 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
if( c->eof ) if( c->eof )
return -1; return -1;
for( ; c->sl; c->sl = c->sl->next ) { /* FIXME: This assumes a plain keyring file */
for( ; c->name; c->name = enum_keyblock_resources( &c->sequence, 1 ) ) {
if( !c->iobuf ) { if( !c->iobuf ) {
if( !(c->iobuf = iobuf_open( c->sl->d ) ) ) { if( !(c->iobuf = iobuf_open( c->name ) ) ) {
log_error("enum_secret_keys: can't open '%s'\n", c->sl->d ); log_error("enum_secret_keys: can't open '%s'\n", c->name );
continue; /* try next file */ continue; /* try next file */
} }
} }
@ -1165,7 +1122,7 @@ get_user_id_string( u32 *keyid )
user_id_db_t r; user_id_db_t r;
char *p; char *p;
int pass=0; int pass=0;
/* try it two times; second pass reads from keyrings */ /* try it two times; second pass reads from key resources */
do { do {
for(r=user_id_db; r; r = r->next ) for(r=user_id_db; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) { if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
@ -1185,7 +1142,7 @@ get_user_id( u32 *keyid, size_t *rn )
user_id_db_t r; user_id_db_t r;
char *p; char *p;
int pass=0; int pass=0;
/* try it two times; second pass reads from keyrings */ /* try it two times; second pass reads from key resources */
do { do {
for(r=user_id_db; r; r = r->next ) for(r=user_id_db; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) { if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {

View File

@ -96,6 +96,7 @@ import_keys( const char *fname )
memset( &afx, 0, sizeof afx); memset( &afx, 0, sizeof afx);
memset( &cfx, 0, sizeof cfx); memset( &cfx, 0, sizeof cfx);
afx.only_keyblocks = 1;
/* open file */ /* open file */
inp = iobuf_open(fname); inp = iobuf_open(fname);

View File

@ -106,10 +106,6 @@ void set_next_passphrase( const char *s );
char *get_last_passphrase(void); char *get_last_passphrase(void);
/*-- getkey.c --*/ /*-- getkey.c --*/
void add_keyring( const char *name );
const char *get_keyring( int sequence );
const char *get_secret_keyring( int sequence );
void add_secret_keyring( const char *name );
int get_pubkey( PKT_public_key *pk, u32 *keyid ); int get_pubkey( PKT_public_key *pk, u32 *keyid );
int get_pubkey_byname( PKT_public_key *pk, const char *name ); int get_pubkey_byname( PKT_public_key *pk, const char *name );
int get_seckey( PKT_secret_key *sk, u32 *keyid ); int get_seckey( PKT_secret_key *sk, u32 *keyid );
@ -156,7 +152,8 @@ int commit_kbnode( KBNODE *root );
void dump_kbnode( KBNODE node ); void dump_kbnode( KBNODE node );
/*-- ringedit.c --*/ /*-- ringedit.c --*/
int add_keyblock_resource( const char *filename, int force, int secret ); 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 ); 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 find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ); int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );

View File

@ -58,8 +58,8 @@ add_key_expire( PKT_signature *sig, void *opaque )
byte buf[8]; byte buf[8];
u32 u; u32 u;
if( sk->valid_days ) { if( sk->expiredate ) {
u = sk->valid_days * 86400L; u = sk->expiredate;
buf[0] = (u >> 24) & 0xff; buf[0] = (u >> 24) & 0xff;
buf[1] = (u >> 16) & 0xff; buf[1] = (u >> 16) & 0xff;
buf[2] = (u >> 8) & 0xff; buf[2] = (u >> 8) & 0xff;
@ -192,7 +192,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk )
static int static int
gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u16 valid_days, STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expiredate,
int version ) int version )
{ {
int rc; int rc;
@ -214,7 +214,9 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
pk = m_alloc_clear( sizeof *pk ); pk = m_alloc_clear( sizeof *pk );
sk->timestamp = pk->timestamp = make_timestamp(); sk->timestamp = pk->timestamp = make_timestamp();
sk->version = pk->version = version; sk->version = pk->version = version;
sk->valid_days = pk->valid_days = valid_days; if( expiredate && expiredate < sk->timestamp )
expiredate = sk->timestamp; /* key generatio may take long */
sk->expiredate = pk->expiredate = expiredate;
sk->pubkey_algo = pk->pubkey_algo = algo; sk->pubkey_algo = pk->pubkey_algo = algo;
pk->pkey[0] = mpi_copy( skey[0] ); pk->pkey[0] = mpi_copy( skey[0] );
pk->pkey[1] = mpi_copy( skey[1] ); pk->pkey[1] = mpi_copy( skey[1] );
@ -266,7 +268,7 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
*/ */
static int static int
gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u16 valid_days ) STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expiredate )
{ {
int rc; int rc;
int i; int i;
@ -289,7 +291,9 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
pk = m_alloc_clear( sizeof *pk ); pk = m_alloc_clear( sizeof *pk );
sk->timestamp = pk->timestamp = make_timestamp(); sk->timestamp = pk->timestamp = make_timestamp();
sk->version = pk->version = 4; sk->version = pk->version = 4;
sk->valid_days = pk->valid_days = valid_days; if( expiredate && expiredate < pk->timestamp )
expiredate = pk->timestamp; /* key generation may take long */
sk->expiredate = pk->expiredate = expiredate;
sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
pk->pkey[0] = mpi_copy( skey[0] ); pk->pkey[0] = mpi_copy( skey[0] );
pk->pkey[1] = mpi_copy( skey[1] ); pk->pkey[1] = mpi_copy( skey[1] );
@ -477,11 +481,12 @@ ask_keysize( int algo )
} }
static int static u32
ask_valid_days() ask_expiredate()
{ {
char *answer; char *answer;
int valid_days=0; int valid_days=0;
u32 expiredate = 0;
tty_printf(_("Please specify how long the key should be valid.\n" tty_printf(_("Please specify how long the key should be valid.\n"
" 0 = key does not expire\n" " 0 = key does not expire\n"
@ -513,12 +518,14 @@ ask_valid_days()
continue; continue;
} }
if( !valid_days ) if( !valid_days ) {
tty_printf(_("Key does not expire at all\n")); tty_printf(_("Key does not expire at all\n"));
expiredate = 0;
}
else { else {
expiredate = make_timestamp() + valid_days * 86400L;
/* print the date when the key expires */ /* print the date when the key expires */
tty_printf(_("Key expires at %s\n"), strtimestamp( tty_printf(_("Key expires at %s\n"), asctimestamp(expiredate) );
add_days_to_timestamp( make_timestamp(), valid_days )));
} }
if( !cpr_enabled() if( !cpr_enabled()
@ -527,7 +534,7 @@ ask_valid_days()
break; break;
} }
m_free(answer); m_free(answer);
return valid_days; return expiredate;
} }
@ -713,7 +720,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
static int static int
do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, int valid_days, DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate,
int v4_packet ) int v4_packet )
{ {
int rc=0; int rc=0;
@ -726,11 +733,13 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E )
rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k,
sk, valid_days, v4_packet? 4:3 ); sk, expiredate, v4_packet? 4:3 );
else if( algo == PUBKEY_ALGO_DSA ) else if( algo == PUBKEY_ALGO_DSA )
rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, valid_days); rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
else else
BUG(); BUG();
#ifdef ENABLE_COMMENT_PACKETS
if( !rc ) { if( !rc ) {
add_kbnode( pub_root, add_kbnode( pub_root,
make_comment_node("#created by GNUPG v" VERSION " (" make_comment_node("#created by GNUPG v" VERSION " ("
@ -739,6 +748,7 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
make_comment_node("#created by GNUPG v" VERSION " (" make_comment_node("#created by GNUPG v" VERSION " ("
PRINTABLE_OS_NAME ")")); PRINTABLE_OS_NAME ")"));
} }
#endif
return rc; return rc;
} }
@ -781,7 +791,7 @@ generate_keypair()
STRING2KEY *s2k; STRING2KEY *s2k;
int rc; int rc;
int algo; int algo;
int ndays; u32 expiredate;
int v4; int v4;
int both = 0; int both = 0;
@ -797,7 +807,7 @@ generate_keypair()
tty_printf(_("DSA keypair will have 1024 bits.\n")); tty_printf(_("DSA keypair will have 1024 bits.\n"));
} }
nbits = ask_keysize( algo ); nbits = ask_keysize( algo );
ndays = ask_valid_days(); expiredate = ask_expiredate();
uid = ask_user_id(0); uid = ask_user_id(0);
if( !uid ) { if( !uid ) {
log_error(_("Key generation cancelled.\n")); log_error(_("Key generation cancelled.\n"));
@ -824,10 +834,10 @@ generate_keypair()
if( both ) if( both )
rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root, rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root,
dek, s2k, &sk, ndays, 1); dek, s2k, &sk, expiredate, 1);
else else
rc = do_create( algo, nbits, pub_root, sec_root, rc = do_create( algo, nbits, pub_root, sec_root,
dek, s2k, &sk, ndays, v4); dek, s2k, &sk, expiredate, v4);
if( !rc ) if( !rc )
write_uid(pub_root, uid ); write_uid(pub_root, uid );
if( !rc ) if( !rc )
@ -839,7 +849,7 @@ generate_keypair()
if( both ) { if( both ) {
rc = do_create( algo, nbits, pub_root, sec_root, rc = do_create( algo, nbits, pub_root, sec_root,
dek, s2k, NULL, ndays, 1 ); dek, s2k, NULL, expiredate, 1 );
if( !rc ) if( !rc )
rc = write_keybinding(pub_root, pub_root, sk); rc = write_keybinding(pub_root, pub_root, sk);
if( !rc ) if( !rc )
@ -927,7 +937,8 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
int okay=0, rc=0; int okay=0, rc=0;
KBNODE node; KBNODE node;
PKT_secret_key *sk = NULL; /* this is the primary sk */ PKT_secret_key *sk = NULL; /* this is the primary sk */
int v4, algo, ndays; int v4, algo;
u32 expiredate;
unsigned nbits; unsigned nbits;
char *passphrase = NULL; char *passphrase = NULL;
DEK *dek = NULL; DEK *dek = NULL;
@ -964,7 +975,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
algo = ask_algo( &v4, 1 ); algo = ask_algo( &v4, 1 );
assert(algo); assert(algo);
nbits = ask_keysize( algo ); nbits = ask_keysize( algo );
ndays = ask_valid_days(); expiredate = ask_expiredate();
if( !cpr_enabled() && !cpr_get_answer_is_yes(N_("keygen.sub.okay"), if( !cpr_enabled() && !cpr_get_answer_is_yes(N_("keygen.sub.okay"),
_("Really create? ") ) ) _("Really create? ") ) )
goto leave; goto leave;
@ -978,7 +989,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
} }
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
dek, s2k, NULL, ndays, v4 ); dek, s2k, NULL, expiredate, v4 );
if( !rc ) if( !rc )
rc = write_keybinding(pub_keyblock, pub_keyblock, sk); rc = write_keybinding(pub_keyblock, pub_keyblock, sk);
if( !rc ) if( !rc )

View File

@ -82,7 +82,12 @@ do_fingerprint_md( PKT_public_key *pk )
md_putc( md, a ); md_putc( md, a );
} }
if( pk->version < 4 ) { if( pk->version < 4 ) {
u16 a = pk->valid_days; u16 a;
if( pk->expiredate )
a = (u16)((pk->expiredate - pk->timestamp) / 86400L);
else
a = 0;
md_putc( md, a >> 8 ); md_putc( md, a >> 8 );
md_putc( md, a ); md_putc( md, a );
} }
@ -108,7 +113,7 @@ do_fingerprint_md_sk( PKT_secret_key *sk )
pk.pubkey_algo = sk->pubkey_algo; pk.pubkey_algo = sk->pubkey_algo;
pk.version = sk->version; pk.version = sk->version;
pk.timestamp = sk->timestamp; pk.timestamp = sk->timestamp;
pk.valid_days = sk->valid_days; pk.expiredate = sk->expiredate;
pk.pubkey_algo = sk->pubkey_algo; pk.pubkey_algo = sk->pubkey_algo;
for( i=0; i < npkey; i++ ) for( i=0; i < npkey; i++ )
pk.pkey[i] = sk->skey[i]; pk.pkey[i] = sk->skey[i];
@ -303,9 +308,9 @@ expirestr_from_pk( PKT_public_key *pk )
struct tm *tp; struct tm *tp;
time_t atime; time_t atime;
if( !pk->valid_days ) if( !pk->expiredate )
return "never "; return "never ";
atime = add_days_to_timestamp( pk->timestamp, pk->valid_days ); atime = pk->expiredate;
tp = gmtime( &atime ); tp = gmtime( &atime );
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
return buffer; return buffer;
@ -318,9 +323,9 @@ expirestr_from_sk( PKT_secret_key *sk )
struct tm *tp; struct tm *tp;
time_t atime; time_t atime;
if( !sk->valid_days ) if( !sk->expiredate )
return "never "; return "never ";
atime = add_days_to_timestamp( sk->timestamp, sk->valid_days ); atime = sk->expiredate;
tp = gmtime( &atime ); tp = gmtime( &atime );
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
return buffer; return buffer;

View File

@ -74,7 +74,8 @@ list_all( int secret )
const char *s; const char *s;
IOBUF a; IOBUF a;
while( (s=secret? get_secret_keyring(seq++):get_keyring(seq++)) ) { /* FIXME: this assumes a keyring resource is a plain keyring file */
while( (s = enum_keyblock_resources( &seq, secret )) ) {
if( !(a = iobuf_open(s)) ) { if( !(a = iobuf_open(s)) ) {
log_error(_("can't open %s: %s\n"), s, strerror(errno)); log_error(_("can't open %s: %s\n"), s, strerror(errno));
continue; continue;
@ -133,12 +134,12 @@ list_one( const char *name, int secret )
sk = node->pkt->pkt.secret_key; sk = node->pkt->pkt.secret_key;
keyid_from_sk( sk, keyid ); keyid_from_sk( sk, keyid );
if( opt.with_colons ) if( opt.with_colons )
printf("sec::%u:%d:%08lX%08lX:%s:%u:::", printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
nbits_from_sk( sk ), nbits_from_sk( sk ),
sk->pubkey_algo, sk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1], (ulong)keyid[0],(ulong)keyid[1],
datestr_from_sk( sk ), datestr_from_sk( sk ),
(unsigned)sk->valid_days sk->expiredate? strtimestamp(sk->expiredate):""
/* fixme: add LID here */ ); /* fixme: add LID here */ );
else else
printf("sec %4u%c/%08lX %s ", nbits_from_sk( sk ), printf("sec %4u%c/%08lX %s ", nbits_from_sk( sk ),
@ -152,13 +153,14 @@ list_one( const char *name, int secret )
keyid_from_pk( pk, keyid ); keyid_from_pk( pk, keyid );
if( opt.with_colons ) { if( opt.with_colons ) {
trustletter = query_trust_info( pk ); trustletter = query_trust_info( pk );
printf("pub:%c:%u:%d:%08lX%08lX:%s:%u:", printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
trustletter, trustletter,
nbits_from_pk( pk ), nbits_from_pk( pk ),
pk->pubkey_algo, pk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1], (ulong)keyid[0],(ulong)keyid[1],
datestr_from_pk( pk ), datestr_from_pk( pk ),
(unsigned)pk->valid_days ); pk->expiredate? strtimestamp(pk->expiredate):""
);
if( pk->local_id ) if( pk->local_id )
printf("%lu", pk->local_id ); printf("%lu", pk->local_id );
putchar(':'); putchar(':');
@ -206,13 +208,13 @@ list_one( const char *name, int secret )
keyid_from_pk( pk2, keyid2 ); keyid_from_pk( pk2, keyid2 );
if( opt.with_colons ) { if( opt.with_colons ) {
printf("sub:%c:%u:%d:%08lX%08lX:%s:%u:", printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
trustletter, trustletter,
nbits_from_pk( pk2 ), nbits_from_pk( pk2 ),
pk2->pubkey_algo, pk2->pubkey_algo,
(ulong)keyid2[0],(ulong)keyid2[1], (ulong)keyid2[0],(ulong)keyid2[1],
datestr_from_pk( pk2 ), datestr_from_pk( pk2 ),
(unsigned)pk2->valid_days pk2->expiredate? strtimestamp(pk2->expiredate):""
/* fixme: add LID and ownertrust here */ /* fixme: add LID and ownertrust here */
); );
if( pk->local_id ) /* use the local_id of the main key??? */ if( pk->local_id ) /* use the local_id of the main key??? */
@ -242,12 +244,12 @@ list_one( const char *name, int secret )
keyid_from_sk( sk2, keyid2 ); keyid_from_sk( sk2, keyid2 );
if( opt.with_colons ) if( opt.with_colons )
printf("ssb::%u:%d:%08lX%08lX:%s:%u:::\n", printf("ssb::%u:%d:%08lX%08lX:%s:%s:::\n",
nbits_from_sk( sk2 ), nbits_from_sk( sk2 ),
sk2->pubkey_algo, sk2->pubkey_algo,
(ulong)keyid2[0],(ulong)keyid2[1], (ulong)keyid2[0],(ulong)keyid2[1],
datestr_from_sk( sk2 ), datestr_from_sk( sk2 ),
(unsigned)sk2->valid_days sk2->expiredate? strtimestamp(sk2->expiredate):""
/* fixme: add LID */ /* fixme: add LID */
); );
else else

View File

@ -471,14 +471,14 @@ list_node( CTX c, KBNODE node )
c->local_id = pk->local_id; c->local_id = pk->local_id;
c->trustletter = query_trust_info( pk ); c->trustletter = query_trust_info( pk );
} }
printf("%s:%c:%u:%d:%08lX%08lX:%s:%u:", printf("%s:%c:%u:%d:%08lX%08lX:%s:%s:",
mainkey? "pub":"sub", mainkey? "pub":"sub",
c->trustletter, c->trustletter,
nbits_from_pk( pk ), nbits_from_pk( pk ),
pk->pubkey_algo, pk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1], (ulong)keyid[0],(ulong)keyid[1],
datestr_from_pk( pk ), datestr_from_pk( pk ),
(unsigned)pk->valid_days ); pk->expiredate? strtimestamp(pk->expiredate):"" );
if( c->local_id ) if( c->local_id )
printf("%lu", c->local_id ); printf("%lu", c->local_id );
putchar(':'); putchar(':');
@ -541,13 +541,13 @@ list_node( CTX c, KBNODE node )
if( opt.with_colons ) { if( opt.with_colons ) {
u32 keyid[2]; u32 keyid[2];
keyid_from_sk( sk, keyid ); keyid_from_sk( sk, keyid );
printf("%s::%u:%d:%08lX%08lX:%s:%u:::", printf("%s::%u:%d:%08lX%08lX:%s:%s:::",
mainkey? "sec":"ssb", mainkey? "sec":"ssb",
nbits_from_sk( sk ), nbits_from_sk( sk ),
sk->pubkey_algo, sk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1], (ulong)keyid[0],(ulong)keyid[1],
datestr_from_sk( sk ), datestr_from_sk( sk ),
(unsigned)sk->valid_days sk->expiredate? strtimestamp(sk->expiredate):""
/* fixme: add LID */ ); /* fixme: add LID */ );
} }
else else

View File

@ -20,6 +20,10 @@
#ifndef G10_OPTIONS_H #ifndef G10_OPTIONS_H
#define G10_OPTIONS_H #define G10_OPTIONS_H
#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */
struct { struct {
int verbose; int verbose;
unsigned debug; unsigned debug;
@ -37,7 +41,7 @@ struct {
int no_armor; int no_armor;
int list_packets; /* list-packets mode */ int list_packets; /* list-packets mode */
int def_cipher_algo; int def_cipher_algo;
int do_not_export_rsa; int reserved1;
int def_digest_algo; int def_digest_algo;
int def_compress_algo; int def_compress_algo;
const char *def_secret_key; const char *def_secret_key;

View File

@ -111,7 +111,7 @@ typedef struct {
*/ */
typedef struct { typedef struct {
u32 timestamp; /* key made */ u32 timestamp; /* key made */
u16 valid_days; /* valid for this number of days */ u32 expiredate; /* expires at this date or 0 if not at all */
byte hdrbytes; /* number of header bytes */ byte hdrbytes; /* number of header bytes */
byte version; byte version;
byte pubkey_algo; /* algorithm used for public key scheme */ byte pubkey_algo; /* algorithm used for public key scheme */
@ -124,7 +124,7 @@ typedef struct {
typedef struct { typedef struct {
u32 timestamp; /* key made */ u32 timestamp; /* key made */
u16 valid_days; /* valid for this number of days */ u32 expiredate; /* expires at this date or 0 if not at all */
byte hdrbytes; /* number of header bytes */ byte hdrbytes; /* number of header bytes */
byte version; byte version;
byte pubkey_algo; /* algorithm used for public key scheme */ byte pubkey_algo; /* algorithm used for public key scheme */

View File

@ -917,8 +917,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
{ {
int i, version, algorithm; int i, version, algorithm;
unsigned n; unsigned n;
unsigned long timestamp; unsigned long timestamp, expiredate;
unsigned short valid_period;
int npkey, nskey; int npkey, nskey;
int is_v4=0; int is_v4=0;
int rc=0; int rc=0;
@ -956,25 +955,30 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
timestamp = read_32(inp); pktlen -= 4; timestamp = read_32(inp); pktlen -= 4;
if( is_v4 ) if( is_v4 )
valid_period = 0; expiredate = 0; /* have to get it from the selfsignature */
else { else {
valid_period = read_16(inp); pktlen -= 2; unsigned short ndays;
ndays = read_16(inp); pktlen -= 2;
if( ndays )
expiredate = timestamp + ndays * 86400L;
else
expiredate = 0;
} }
algorithm = iobuf_get_noeof(inp); pktlen--; algorithm = iobuf_get_noeof(inp); pktlen--;
if( list_mode ) if( list_mode )
printf(":%s key packet:\n" printf(":%s key packet:\n"
"\tversion %d, algo %d, created %lu, valid for %hu days\n", "\tversion %d, algo %d, created %lu, expires %lu\n",
pkttype == PKT_PUBLIC_KEY? "public" : pkttype == PKT_PUBLIC_KEY? "public" :
pkttype == PKT_SECRET_KEY? "secret" : pkttype == PKT_SECRET_KEY? "secret" :
pkttype == PKT_PUBLIC_SUBKEY? "public sub" : pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??", pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
version, algorithm, timestamp, valid_period ); version, algorithm, timestamp, expiredate );
if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) { if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
PKT_secret_key *sk = pkt->pkt.secret_key; PKT_secret_key *sk = pkt->pkt.secret_key;
sk->timestamp = timestamp; sk->timestamp = timestamp;
sk->valid_days = valid_period; sk->expiredate = expiredate;
sk->hdrbytes = hdrlen; sk->hdrbytes = hdrlen;
sk->version = version; sk->version = version;
sk->pubkey_algo = algorithm; sk->pubkey_algo = algorithm;
@ -984,7 +988,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
PKT_public_key *pk = pkt->pkt.public_key; PKT_public_key *pk = pkt->pkt.public_key;
pk->timestamp = timestamp; pk->timestamp = timestamp;
pk->valid_days = valid_period; pk->expiredate = expiredate;
pk->hdrbytes = hdrlen; pk->hdrbytes = hdrlen;
pk->version = version; pk->version = version;
pk->pubkey_algo = algorithm; pk->pubkey_algo = algorithm;

View File

@ -48,6 +48,7 @@
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> /* for truncate */
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "packet.h" #include "packet.h"
@ -55,8 +56,8 @@
#include "mpi.h" #include "mpi.h"
#include "iobuf.h" #include "iobuf.h"
#include "keydb.h" #include "keydb.h"
#include "options.h"
#include "i18n.h" #include "i18n.h"
#include <unistd.h> /* for truncate */
struct resource_table_struct { struct resource_table_struct {
@ -96,30 +97,76 @@ check_pos( KBPOS *kbpos )
****************** public functions **************************** ****************** public functions ****************************
****************************************************************/ ****************************************************************/
/****************
* Get the name of the keyrings, start with a sequence number pointing to a 0.
*/
const char *
enum_keyblock_resources( int *sequence, int secret )
{
int i = *sequence;
const char *name = NULL;
for(; i < MAX_RESOURCES; i++ )
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
if( resource_table[i].fname ) {
name = resource_table[i].fname;
break;
}
}
*sequence = ++i;
return NULL; /* not found */
}
/**************** /****************
* Register a resource (which currently may only be a keyring file). * Register a resource (which currently may only be a keyring file).
* The first keyring which is added by this function is
* created if it does not exist.
* Note: this function may be called before secure memory is
* available.
*/ */
int int
add_keyblock_resource( const char *filename, int force, int secret ) add_keyblock_resource( const char *resname, int force, int secret )
{ {
static int any_secret, any_public;
IOBUF iobuf; IOBUF iobuf;
int i; int i, force;
char *filename;
int rc = 0;
if( *resname != '/' ) { /* do tilde expansion etc */
if( strchr(resname, '/') )
filename = make_filename(resname, NULL);
else
filename = make_filename(opt.homedir, resname, NULL);
}
else
filename = m_strdup( resname );
if( !force )
force = secret? !any_secret : !any_public;
for(i=0; i < MAX_RESOURCES; i++ ) for(i=0; i < MAX_RESOURCES; i++ )
if( !resource_table[i].used ) if( !resource_table[i].used )
break; break;
if( i == MAX_RESOURCES ) if( i == MAX_RESOURCES ) {
return G10ERR_RESOURCE_LIMIT; rc = G10ERR_RESOURCE_LIMIT;
goto leave;
}
iobuf = iobuf_open( filename ); iobuf = iobuf_fopen( filename, "rb" );
if( !iobuf && !force ) if( !iobuf && !force ) {
return G10ERR_OPEN_FILE; rc = G10ERR_OPEN_FILE;
goto leave;
}
if( !iobuf ) { if( !iobuf ) {
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: %s\n", filename, strerror(errno));
return G10ERR_OPEN_FILE; rc = G10ERR_OPEN_FILE;
goto leave;
} }
else else
log_info("%s: keyring created\n", filename ); log_info("%s: keyring created\n", filename );
@ -135,7 +182,15 @@ add_keyblock_resource( const char *filename, int force, int secret )
resource_table[i].secret = !!secret; resource_table[i].secret = !!secret;
resource_table[i].fname = m_strdup(filename); resource_table[i].fname = m_strdup(filename);
resource_table[i].iobuf = iobuf; resource_table[i].iobuf = iobuf;
return 0; leave:
if( rc )
log_error("keyblock resource '%s': %s\n", filename, g10_errstr(rc) );
else if( secret )
any_secret = 1;
else
any_public = 1;
m_free( filename );
return rc;
} }
/**************** /****************
@ -362,7 +417,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
return -1; /* no resources */ return -1; /* no resources */
kbpos->resno = i; kbpos->resno = i;
rentry = check_pos( kbpos ); rentry = check_pos( kbpos );
kbpos->fp = iobuf_open( rentry->fname ); kbpos->fp = iobuf_fopen( rentry->fname, "rb" );
if( !kbpos->fp ) { if( !kbpos->fp ) {
log_error("can't open '%s'\n", rentry->fname ); log_error("can't open '%s'\n", rentry->fname );
return G10ERR_OPEN_FILE; return G10ERR_OPEN_FILE;
@ -528,7 +583,6 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
PKT_secret_key *sk = pkt.pkt.secret_key; PKT_secret_key *sk = pkt.pkt.secret_key;
if( req_sk->timestamp == sk->timestamp if( req_sk->timestamp == sk->timestamp
&& req_sk->valid_days == sk->valid_days
&& req_sk->pubkey_algo == sk->pubkey_algo && req_sk->pubkey_algo == sk->pubkey_algo
&& !cmp_seckey( req_sk, sk) ) && !cmp_seckey( req_sk, sk) )
break; /* found */ break; /* found */
@ -537,7 +591,6 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
PKT_public_key *pk = pkt.pkt.public_key; PKT_public_key *pk = pkt.pkt.public_key;
if( req_pk->timestamp == pk->timestamp if( req_pk->timestamp == pk->timestamp
&& req_pk->valid_days == pk->valid_days
&& req_pk->pubkey_algo == pk->pubkey_algo && req_pk->pubkey_algo == pk->pubkey_algo
&& !cmp_pubkey( req_pk, pk ) ) && !cmp_pubkey( req_pk, pk ) )
break; /* found */ break; /* found */
@ -572,7 +625,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
if( !(rentry=check_pos(kbpos)) ) if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL; return G10ERR_GENERAL;
a = iobuf_open( rentry->fname ); a = iobuf_fopen( rentry->fname, "rb" );
if( !a ) { if( !a ) {
log_error("can't open '%s'\n", rentry->fname ); log_error("can't open '%s'\n", rentry->fname );
return G10ERR_OPEN_FILE; return G10ERR_OPEN_FILE;
@ -732,7 +785,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
BUG(); /* not allowed with such a handle */ BUG(); /* not allowed with such a handle */
/* open the source file */ /* open the source file */
fp = iobuf_open( rentry->fname ); fp = iobuf_fopen( rentry->fname, "rb" );
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */ if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
KBNODE kbctx, node; KBNODE kbctx, node;

View File

@ -166,11 +166,9 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
return G10ERR_TIME_CONFLICT; return G10ERR_TIME_CONFLICT;
} }
if( pk->valid_days && add_days_to_timestamp(pk->timestamp, if( pk->expiredate && pk->expiredate < cur_time ) {
pk->valid_days) < cur_time ) { log_info(_("warning: signature key expired %s\n"),
log_info(_("warning: signature key expired %s\n"), strtimestamp( asctimestamp( pk->expiredate ) );
add_days_to_timestamp(pk->timestamp,
pk->valid_days)));
write_status(STATUS_SIGEXPIRED); write_status(STATUS_SIGEXPIRED);
} }

View File

@ -225,12 +225,14 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if( opt.armor && !outfile ) if( opt.armor && !outfile )
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
#ifdef ENABLE_COMMENT_PACKETS
else { else {
write_comment( out, "#created by GNUPG v" VERSION " (" write_comment( out, "#created by GNUPG v" VERSION " ("
PRINTABLE_OS_NAME ")"); PRINTABLE_OS_NAME ")");
if( opt.comment_string ) if( opt.comment_string )
write_comment( out, opt.comment_string ); write_comment( out, opt.comment_string );
} }
#endif
if( encrypt ) { if( encrypt ) {
efx.pk_list = pk_list; efx.pk_list = pk_list;
/* fixme: set efx.cfx.datalen if known */ /* fixme: set efx.cfx.datalen if known */

View File

@ -39,6 +39,27 @@
#include "trustdb.h" #include "trustdb.h"
#include "tdbio.h" #include "tdbio.h"
/****************
* Yes, this is a very simple implementation. We should really
* use a page aligned buffer and read complete pages.
* To implement a simple trannsaction system, this is sufficient.
*/
typedef struct cache_ctrl_struct *CACHE_CTRL;
struct cache_ctrl_struct {
CACHE_CTRL next;
struct {
unsigned used:1;
unsigned dirty:1;
} flags;
ulong recno;
char data[TRUST_RECORD_LEN];
};
#define MAX_CACHE_ENTRIES 200
static CACHE_CTRL cache_list;
static int cache_entries;
/* a type used to pass infomation to cmp_krec_fpr */ /* a type used to pass infomation to cmp_krec_fpr */
struct cmp_krec_fpr_struct { struct cmp_krec_fpr_struct {
int pubkey_algo; int pubkey_algo;
@ -59,6 +80,184 @@ static int db_fd = -1;
static void open_db(void); static void open_db(void);
/*************************************
************* record cache **********
*************************************/
/****************
* Get the data from therecord cache and return a
* pointer into that cache. Caller should copy
* the return data. NULL is returned on a cache miss.
*/
static const char *
get_record_from_cache( ulong recno )
{
CACHE_CTRL r;
for( r = cache_list; r; r = r->next ) {
if( r->flags.used && r->recno == recno )
return r->data;
}
return NULL;
}
static int
write_cache_item( CACHE_CTRL r )
{
int n;
if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
log_error(_("trustdb rec %lu: lseek failed: %s\n"),
r->recno, strerror(errno) );
return G10ERR_WRITE_FILE;
}
n = write( db_fd, r->data, TRUST_RECORD_LEN);
if( n != TRUST_RECORD_LEN ) {
log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
r->recno, n, strerror(errno) );
return G10ERR_WRITE_FILE;
}
r->flags.dirty = 0;
return 0;
}
/****************
* Put data into the cache. This function may flush the
* some cache entries if there is not enough space available.
*/
int
put_record_into_cache( ulong recno, const char *data )
{
CACHE_CTRL r, unused;
int dirty_count = 0;
int clean_count = 0;
/* see whether we already cached this one */
for( unused = NULL, r = cache_list; r; r = r->next ) {
if( !r->flags.used ) {
if( !unused )
unused = r;
}
else if( r->recno == recno ) {
if( !r->flags.dirty ) {
/* Hmmm: should we use a a copy and compare? */
if( memcmp(r->data, data, TRUST_RECORD_LEN ) )
r->flags.dirty = 1;
}
memcpy( r->data, data, TRUST_RECORD_LEN );
return 0;
}
if( r->flags.used ) {
if( r->flags.dirty )
dirty_count++;
else
clean_count++;
}
}
/* not in the cache: add a new entry */
if( unused ) { /* reuse this entry */
r = unused;
r->flags.used = 1;
r->recno = recno;
memcpy( r->data, data, TRUST_RECORD_LEN );
r->flags.dirty = 1;
cache_entries++;
return 0;
}
/* see whether we reached the limit */
if( cache_entries < MAX_CACHE_ENTRIES ) { /* no */
r = m_alloc( sizeof *r );
r->flags.used = 1;
r->recno = recno;
memcpy( r->data, data, TRUST_RECORD_LEN );
r->flags.dirty = 1;
r->next = cache_list;
cache_list = r;
cache_entries++;
return 0;
}
/* cache is full: discard some clean entries */
if( clean_count ) {
int n = clean_count / 3; /* discard a third of the clean entries */
if( !n )
n = 1;
for( unused = NULL, r = cache_list; r; r = r->next ) {
if( r->flags.used && !r->flags.dirty ) {
if( !unused )
unused = r;
r->flags.used = 0;
cache_entries--;
if( !--n )
break;
}
}
assert( unused );
r = unused;
r->flags.used = 1;
r->recno = recno;
memcpy( r->data, data, TRUST_RECORD_LEN );
r->flags.dirty = 1;
cache_entries++;
return 0;
}
/* no clean entries: have to flush some dirty entries */
if( dirty_count ) {
int n = dirty_count / 5; /* discard some dirty entries */
if( !n )
n = 1;
for( unused = NULL, r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r );
if( rc )
return rc;
if( !unused )
unused = r;
r->flags.used = 0;
cache_entries--;
if( !--n )
break;
}
}
assert( unused );
r = unused;
r->flags.used = 1;
r->recno = recno;
memcpy( r->data, data, TRUST_RECORD_LEN );
r->flags.dirty = 1;
cache_entries++;
return 0;
}
BUG();
}
/****************
* Sync the cache to disk
*/
int
tdbio_sync()
{
CACHE_CTRL r;
for( r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r );
if( rc )
return rc;
}
}
return 0;
}
/********************************************************
**************** cached I/O functions ******************
********************************************************/
int int
tdbio_set_dbname( const char *new_dbname, int create ) tdbio_set_dbname( const char *new_dbname, int create )
@ -118,6 +317,8 @@ tdbio_set_dbname( const char *new_dbname, int create )
rec.rectype = RECTYPE_VER; rec.rectype = RECTYPE_VER;
rec.recnum = 0; rec.recnum = 0;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( !rc )
tdbio_sync();
if( rc ) if( rc )
log_fatal_f( fname, _("failed to create version record: %s"), log_fatal_f( fname, _("failed to create version record: %s"),
g10_errstr(rc)); g10_errstr(rc));
@ -185,7 +386,7 @@ create_hashtable( TRUSTREC *vr, int type )
n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD; n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
for(i=0; i < n; i++, recnum++ ) { for(i=0; i < n; i++, recnum++ ) {
memset( &rec, 0, sizeof rec ); memset( &rec, 0, sizeof rec );
rec.rectype = RECTYPE_HTBL; /* free record */ rec.rectype = RECTYPE_HTBL;
rec.recnum = recnum; rec.recnum = recnum;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) if( rc )
@ -194,6 +395,8 @@ create_hashtable( TRUSTREC *vr, int type )
} }
/* update the version record */ /* update the version record */
rc = tdbio_write_record( vr ); rc = tdbio_write_record( vr );
if( !rc )
rc = tdbio_sync();
if( rc ) if( rc )
log_fatal_f( db_name, _("error updating version record: %s\n"), log_fatal_f( db_name, _("error updating version record: %s\n"),
g10_errstr(rc)); g10_errstr(rc));
@ -208,12 +411,11 @@ static ulong
get_keyhashrec() get_keyhashrec()
{ {
static ulong keyhashtbl; /* record number of the key hashtable */ static ulong keyhashtbl; /* record number of the key hashtable */
if( !keyhashtbl ) {
TRUSTREC vr; TRUSTREC vr;
int rc; int rc;
if( keyhashtbl )
return keyhashtbl;
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_f( db_name, _("error reading version record: %s\n"),
@ -221,8 +423,9 @@ get_keyhashrec()
if( !vr.r.ver.keyhashtbl ) if( !vr.r.ver.keyhashtbl )
create_hashtable( &vr, 0 ); create_hashtable( &vr, 0 );
keyhashtbl = vr.r.ver.keyhashtbl;
return vr.r.ver.keyhashtbl; }
return keyhashtbl;
} }
/**************** /****************
@ -233,12 +436,11 @@ static ulong
get_sdirhashrec() get_sdirhashrec()
{ {
static ulong sdirhashtbl; /* record number of the hashtable */ static ulong sdirhashtbl; /* record number of the hashtable */
if( !sdirhashtbl ) {
TRUSTREC vr; TRUSTREC vr;
int rc; int rc;
if( sdirhashtbl )
return sdirhashtbl;
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_f( db_name, _("error reading version record: %s\n"),
@ -246,7 +448,9 @@ get_sdirhashrec()
if( !vr.r.ver.sdirhashtbl ) if( !vr.r.ver.sdirhashtbl )
create_hashtable( &vr, 1 ); create_hashtable( &vr, 1 );
return vr.r.ver.sdirhashtbl; sdirhashtbl = vr.r.ver.sdirhashtbl;
}
return sdirhashtbl;
} }
@ -289,15 +493,16 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
lastrec = rec; lastrec = rec;
rc = tdbio_read_record( item, &rec, 0 ); rc = tdbio_read_record( item, &rec, 0 );
if( rc ) { if( rc ) {
log_error( db_name, "upd_hashtable: read item failed: %s\n", log_error( "upd_hashtable: read item failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; return rc;
} }
if( rec.rectype == RECTYPE_HTBL ) { if( rec.rectype == RECTYPE_HTBL ) {
hashrec = item; hashrec = item;
level++; level++;
if( level >= keylen ) { if( level >= keylen ) {
log_error( db_name, "hashtable has invalid indirections.\n"); log_error( "hashtable has invalid indirections.\n");
return G10ERR_TRUSTDB; return G10ERR_TRUSTDB;
} }
goto next_level; goto next_level;
@ -314,8 +519,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rc = tdbio_read_record( rec.r.hlst.next, rc = tdbio_read_record( rec.r.hlst.next,
&rec, RECTYPE_HLST); &rec, RECTYPE_HLST);
if( rc ) { if( rc ) {
log_error( db_name, log_error( "scan keyhashtbl read hlst failed: %s\n",
"scan keyhashtbl read hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; return rc;
} }
@ -330,8 +534,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rec.r.hlst.rnum[i] = newrecnum; rec.r.hlst.rnum[i] = newrecnum;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) if( rc )
log_error( db_name, log_error( "upd_hashtable: write hlst failed: %s\n",
"upd_hashtable: write hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; /* done */ return rc; /* done */
} }
@ -340,8 +543,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rc = tdbio_read_record( rec.r.hlst.next, rc = tdbio_read_record( rec.r.hlst.next,
&rec, RECTYPE_HLST ); &rec, RECTYPE_HLST );
if( rc ) { if( rc ) {
log_error( db_name, log_error( "upd_hashtable: read hlst failed: %s\n",
"upd_hashtable: read hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; return rc;
} }
@ -350,8 +552,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rec.r.hlst.next = item = tdbio_new_recnum(); rec.r.hlst.next = item = tdbio_new_recnum();
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) { if( rc ) {
log_error( db_name, log_error( "upd_hashtable: write hlst failed: %s\n",
"upd_hashtable: write hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; return rc;
} }
@ -361,14 +562,14 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rec.r.hlst.rnum[0] = newrecnum; rec.r.hlst.rnum[0] = newrecnum;
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) if( rc )
log_error( db_name, log_error( "upd_hashtable: write ext hlst failed: %s\n",
"upd_hashtable: write ext hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; /* done */ return rc; /* done */
} }
} /* end loop over hlst slots */ } /* end loop over hlst slots */
} }
else if( rec.rectype == RECTYPE_KEY else if( rec.rectype == RECTYPE_KEY
|| rec.rectype == RECTYPE_DIR
|| rec.rectype == RECTYPE_SDIR ) { /* insert a list record */ || rec.rectype == RECTYPE_SDIR ) { /* insert a list record */
if( rec.recnum == newrecnum ) { if( rec.recnum == newrecnum ) {
return 0; return 0;
@ -381,8 +582,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
rec.r.hlst.rnum[1] = newrecnum; /* and new one */ rec.r.hlst.rnum[1] = newrecnum; /* and new one */
rc = tdbio_write_record( &rec ); rc = tdbio_write_record( &rec );
if( rc ) { if( rc ) {
log_error( db_name, log_error( "upd_hashtable: write new hlst failed: %s\n",
"upd_hashtable: write new hlst failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; return rc;
} }
@ -390,12 +590,12 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum; lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
rc = tdbio_write_record( &lastrec ); rc = tdbio_write_record( &lastrec );
if( rc ) if( rc )
log_error( db_name, "upd_hashtable: update htbl failed: %s\n", log_error( "upd_hashtable: update htbl failed: %s\n",
g10_errstr(rc) ); g10_errstr(rc) );
return rc; /* ready */ return rc; /* ready */
} }
else { else {
log_error( db_name, "hashtbl %lu points to an invalid record\n", log_error( "hashtbl %lu points to an invalid record\n",
item); item);
return G10ERR_TRUSTDB; return G10ERR_TRUSTDB;
} }
@ -637,24 +837,30 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
int int
tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
{ {
byte buf[TRUST_RECORD_LEN], *p; byte readbuf[TRUST_RECORD_LEN];
const byte *buf, *p;
int rc = 0; int rc = 0;
int n, i; int n, i;
if( db_fd == -1 ) if( db_fd == -1 )
open_db(); open_db();
buf = get_record_from_cache( recnum );
if( !buf ) {
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) ); log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
return G10ERR_READ_FILE; return G10ERR_READ_FILE;
} }
n = read( db_fd, buf, TRUST_RECORD_LEN); n = read( db_fd, readbuf, TRUST_RECORD_LEN);
if( !n ) { if( !n ) {
return -1; /* eof */ return -1; /* eof */
} }
else if( n != TRUST_RECORD_LEN ) { else if( n != TRUST_RECORD_LEN ) {
log_error(_("trustdb: read failed (n=%d): %s\n"), n, strerror(errno) ); log_error(_("trustdb: read failed (n=%d): %s\n"), n,
strerror(errno) );
return G10ERR_READ_FILE; return G10ERR_READ_FILE;
} }
buf = readbuf;
}
rec->recnum = recnum; rec->recnum = recnum;
rec->dirty = 0; rec->dirty = 0;
p = buf; p = buf;
@ -791,14 +997,12 @@ tdbio_write_record( TRUSTREC *rec )
{ {
byte buf[TRUST_RECORD_LEN], *p; byte buf[TRUST_RECORD_LEN], *p;
int rc = 0; int rc = 0;
int i, n; int i;
ulong recnum = rec->recnum; ulong recnum = rec->recnum;
if( db_fd == -1 ) if( db_fd == -1 )
open_db(); open_db();
tdbio_dump_record( rec, stdout );
memset(buf, 0, TRUST_RECORD_LEN); memset(buf, 0, TRUST_RECORD_LEN);
p = buf; p = buf;
*p++ = rec->rectype; p++; *p++ = rec->rectype; p++;
@ -900,16 +1104,10 @@ tdbio_dump_record( rec, stdout );
BUG(); BUG();
} }
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) { rc = put_record_into_cache( recnum, buf );
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) ); if( rc )
return G10ERR_WRITE_FILE; ;
} if( rec->rectype == RECTYPE_KEY )
n = write( db_fd, buf, TRUST_RECORD_LEN);
if( n != TRUST_RECORD_LEN ) {
log_error(_("trustdb: write failed (n=%d): %s\n"), n, strerror(errno) );
return G10ERR_WRITE_FILE;
}
else if( rec->rectype == RECTYPE_KEY )
rc = update_keyhashtbl( rec ); rc = update_keyhashtbl( rec );
else if( rec->rectype == RECTYPE_SDIR ) else if( rec->rectype == RECTYPE_SDIR )
rc = update_sdirhashtbl( rec ); rc = update_sdirhashtbl( rec );
@ -990,7 +1188,21 @@ tdbio_new_recnum()
memset( &rec, 0, sizeof rec ); memset( &rec, 0, sizeof rec );
rec.rectype = 0; /* unused record */ rec.rectype = 0; /* unused record */
rec.recnum = recnum; rec.recnum = recnum;
rc = tdbio_write_record( &rec ); rc = 0;
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
log_error(_("trustdb rec %lu: lseek failed: %s\n"),
recnum, strerror(errno) );
rc = G10ERR_WRITE_FILE;
}
else {
int n = write( db_fd, &rec, TRUST_RECORD_LEN);
if( n != TRUST_RECORD_LEN ) {
log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
recnum, n, strerror(errno) );
rc = G10ERR_WRITE_FILE;
}
}
if( rc ) if( rc )
log_fatal_f(db_name,_("failed to append a record: %s\n"), log_fatal_f(db_name,_("failed to append a record: %s\n"),
g10_errstr(rc)); g10_errstr(rc));

View File

@ -166,6 +166,7 @@ const char *tdbio_get_dbname(void);
void tdbio_dump_record( TRUSTREC *rec, FILE *fp ); void tdbio_dump_record( TRUSTREC *rec, FILE *fp );
int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
int tdbio_write_record( TRUSTREC *rec ); int tdbio_write_record( TRUSTREC *rec );
int tdbio_sync(void);
int tdbio_delete_record( ulong recnum ); int tdbio_delete_record( ulong recnum );
ulong tdbio_new_recnum(void); ulong tdbio_new_recnum(void);
int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ); int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec );

View File

@ -48,7 +48,7 @@ read_line( byte *buf, size_t *r_buflen, IOBUF a )
assert(buflen >= 20 ); assert(buflen >= 20 );
buflen -= 3; /* leave some room for CR,LF and one extra */ buflen -= 3; /* leave some room for CR,LF and one extra */
for(c=0, n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) for(c=0, n=0; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
buf[n++] = c; buf[n++] = c;
buf[n] = 0; buf[n] = 0;
if( c == -1 ) { if( c == -1 ) {
@ -58,7 +58,7 @@ read_line( byte *buf, size_t *r_buflen, IOBUF a )
} }
else if( c != '\n' ) { else if( c != '\n' ) {
IOBUF b = iobuf_temp(); IOBUF b = iobuf_temp();
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) { while( (c=iobuf_get(a)) != -1 && c != '\n' ) {
iobuf_put(b,c); iobuf_put(b,c);
if( c != ' ' && c != '\t' && c != '\r' ) if( c != ' ' && c != '\t' && c != '\r' )
break; break;

View File

@ -71,11 +71,6 @@ struct trust_seg_list {
}; };
typedef struct {
TRUST_SEG_LIST tsl;
int index;
} ENUM_TRUST_WEB_CONTEXT;
struct recno_list_struct { struct recno_list_struct {
struct recno_list_struct *next; struct recno_list_struct *next;
@ -171,6 +166,19 @@ delete_record( ulong recno )
die_invalid_db(); die_invalid_db();
} }
/****************
* sync the db
*/
static void
do_sync( )
{
int rc = tdbio_sync();
if( !rc )
return;
log_error("trust db: sync failed: %s\n", g10_errstr(rc) );
g10_exit(2);
}
/********************************************** /**********************************************
@ -425,15 +433,15 @@ verify_own_keys()
memset( pk, 0, sizeof *pk ); memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid ); rc = get_pubkey( pk, keyid );
if( rc ) { if( rc ) {
log_error(_("key %08lX: secret key without public key\n"), log_info(_("key %08lX: secret key without public key - skipped\n"),
(ulong)keyid[1] ); (ulong)keyid[1] );
goto leave; goto skip;
} }
if( cmp_public_secret_key( pk, sk ) ) { if( cmp_public_secret_key( pk, sk ) ) {
log_error(_("key %08lX: secret and public key don't match\n"), log_info(_("key %08lX: secret and public key don't match\n"),
(ulong)keyid[1] ); (ulong)keyid[1] );
rc = G10ERR_GENERAL; goto skip;
goto leave;
} }
/* make sure that the pubkey is in the trustdb */ /* make sure that the pubkey is in the trustdb */
@ -443,12 +451,12 @@ verify_own_keys()
if( rc ) { if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"), log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] ); (ulong)keyid[1] );
goto leave; goto skip;
} }
} }
else if( rc ) { else if( rc ) {
log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] ); log_error(_("key %08lX: query record failed\n"), (ulong)keyid[1] );
goto leave; goto skip;
} }
@ -456,9 +464,12 @@ verify_own_keys()
log_debug("key %08lX.%lu: stored into ultikey_table\n", log_debug("key %08lX.%lu: stored into ultikey_table\n",
(ulong)keyid[1], pk->local_id ); (ulong)keyid[1], pk->local_id );
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) ) if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in ultikey_table\n"), log_error(_("key %08lX: already in secret key table\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
else if( opt.verbose )
log_info(_("key %08lX: accepted as secret key.\n"),
(ulong)keyid[1]);
skip:
release_secret_key_parts( sk ); release_secret_key_parts( sk );
release_public_key_parts( pk ); release_public_key_parts( pk );
} }
@ -467,7 +478,6 @@ verify_own_keys()
else else
rc = 0; rc = 0;
leave:
enum_secret_keys( &enum_context, NULL, 0 ); /* free context */ enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
free_secret_key( sk ); free_secret_key( sk );
free_public_key( pk ); free_public_key( pk );
@ -695,6 +705,13 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
TRUST_SEG_LIST tsl, t2, tl; TRUST_SEG_LIST tsl, t2, tl;
int i; int i;
if( !(sx.sig_flag & SIGF_CHECKED) )
continue; /* only checked sigs */
if( !(sx.sig_flag & SIGF_VALID) )
continue; /* and, of course, only valid sigs */
if( (sx.sig_flag & SIGF_REVOKED) )
continue; /* and skip revoked sigs */
stack[depth].lid = sx.sig_lid; stack[depth].lid = sx.sig_lid;
stack[depth].trust = 0; stack[depth].trust = 0;
if( qry_lid_table_flag( lids, sx.sig_lid, &last_depth) ) { if( qry_lid_table_flag( lids, sx.sig_lid, &last_depth) ) {
@ -782,8 +799,13 @@ make_tsl( ulong lid, TRUST_SEG_LIST *ret_tslist )
release_lid_table(work); release_lid_table(work);
*ret_tslist = tslist; *ret_tslist = tslist;
} }
else else { /* error: release tslist */
; /* FIXME: release tslist */ while( tslist ) {
tsl = tslist->next;
m_free(tslist);
tslist = tsl;
}
}
release_lid_table(lids); release_lid_table(lids);
return rc; return rc;
} }
@ -865,7 +887,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
if( dr->r.dir.dirflags & DIRF_REVOKED ) if( dr->r.dir.dirflags & DIRF_REVOKED )
tflags |= TRUST_FLAG_REVOKED; tflags |= TRUST_FLAG_REVOKED;
#if 0 #if 0 /* Do we still need this?? */
if( !rc && !dr->r.dir.siglist ) { if( !rc && !dr->r.dir.siglist ) {
/* We do not have any signatures; check whether it is one of our /* We do not have any signatures; check whether it is one of our
* secret keys */ * secret keys */
@ -1153,6 +1175,7 @@ import_ownertrust( const char *fname )
log_error_f(fname, _("read error: %s\n"), strerror(errno) ); log_error_f(fname, _("read error: %s\n"), strerror(errno) );
if( !is_stdin ) if( !is_stdin )
fclose(fp); fclose(fp);
do_sync();
} }
@ -1247,8 +1270,6 @@ list_trust_path( int max_depth, const char *username )
/**************** /****************
* Check the complete trustdb or only the entries for the given username. * Check the complete trustdb or only the entries for the given username.
* Special hack: A username "REBUILD" inserts all records from the public
* key rings into the trustdb.
*/ */
void void
check_trustdb( const char *username ) check_trustdb( const char *username )
@ -1257,9 +1278,8 @@ check_trustdb( const char *username )
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBPOS kbpos; KBPOS kbpos;
int rc; int rc;
int rebuild = username && !strcmp(username, "REBUILD");
if( username && !rebuild ) { if( username ) {
rc = find_keyblock_byname( &kbpos, username ); rc = find_keyblock_byname( &kbpos, username );
if( !rc ) if( !rc )
rc = read_keyblock( &kbpos, &keyblock ); rc = read_keyblock( &kbpos, &keyblock );
@ -1315,8 +1335,16 @@ check_trustdb( const char *username )
release_kbnode( keyblock ); keyblock = NULL; release_kbnode( keyblock ); keyblock = NULL;
} }
} }
if( rebuild ) { }
log_info("adding new entries.\n"); }
void
update_trustdb( )
{
KBNODE keyblock = NULL;
KBPOS kbpos;
int rc;
rc = enum_keyblocks( 0, &kbpos, &keyblock ); rc = enum_keyblocks( 0, &kbpos, &keyblock );
if( !rc ) { if( !rc ) {
@ -1349,9 +1377,6 @@ check_trustdb( const char *username )
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock ); release_kbnode( keyblock );
}
}
} }
@ -1418,12 +1443,10 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
return G10ERR_TIME_CONFLICT; return G10ERR_TIME_CONFLICT;
} }
if( pk->valid_days && add_days_to_timestamp(pk->timestamp, if( pk->expiredate && pk->expiredate <= cur_time ) {
pk->valid_days) < cur_time ) {
log_info(_("key %08lX.%lu: expired at %s\n"), log_info(_("key %08lX.%lu: expired at %s\n"),
(ulong)keyid[1], pk->local_id, (ulong)keyid[1], pk->local_id,
asctimestamp( add_days_to_timestamp(pk->timestamp, asctimestamp( pk->expiredate) );
pk->valid_days)));
trustlevel = TRUST_EXPIRED; trustlevel = TRUST_EXPIRED;
} }
else { else {
@ -1485,7 +1508,10 @@ query_trust_info( PKT_public_key *pk )
int int
enum_trust_web( void **context, ulong *lid ) enum_trust_web( void **context, ulong *lid )
{ {
ENUM_TRUST_WEB_CONTEXT *c = *context; struct {
TRUST_SEG_LIST tsl;
int index;
} *c = *context;
if( !c ) { /* make a new context */ if( !c ) { /* make a new context */
c = m_alloc_clear( sizeof *c ); c = m_alloc_clear( sizeof *c );
@ -1652,7 +1678,7 @@ query_trust_record( PKT_public_key *pk )
return get_dir_record( pk, &rec ); return get_dir_record( pk, &rec );
} }
/* FIXME: Brauchen wir das?? */
int int
clear_trust_checked_flag( PKT_public_key *pk ) clear_trust_checked_flag( PKT_public_key *pk )
{ {
@ -1669,6 +1695,7 @@ clear_trust_checked_flag( PKT_public_key *pk )
/* reset the flag */ /* reset the flag */
rec.r.dir.dirflags &= ~DIRF_CHECKED; rec.r.dir.dirflags &= ~DIRF_CHECKED;
write_record( &rec ); write_record( &rec );
do_sync();
return 0; return 0;
} }
@ -1684,6 +1711,8 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
byte uhash[20]; byte uhash[20];
int is_selfsig; int is_selfsig;
PKT_signature *sigpkt = NULL; PKT_signature *sigpkt = NULL;
TRUSTREC tmp;
u32 sigkid[2];
if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED ) if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
log_info(_("note: sig rec %lu[%d] in hintlist " log_info(_("note: sig rec %lu[%d] in hintlist "
@ -1694,6 +1723,23 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
"of %lu but not marked\n"), "of %lu but not marked\n"),
sigrec->recnum, sigidx, hint_owner ); sigrec->recnum, sigidx, hint_owner );
read_record( sigrec->r.sig.sig[sigidx].lid, &tmp, 0 );
if( tmp.rectype != RECTYPE_DIR ) {
/* we need the dir record */
log_error(_("sig rec %lu[%d] in hintlist "
"of %u does not point to a dir record\n"),
sigrec->recnum, sigidx, hint_owner );
return;
}
if( !tmp.r.dir.keylist ) {
log_error(_("lid %lu: no primary key\n"), tmp.r.dir.lid );
return;
}
read_record(tmp.r.dir.keylist, &tmp, RECTYPE_KEY );
keyid_from_fingerprint( tmp.r.key.fingerprint,
tmp.r.key.fingerprint_len, sigkid );
/* find the correct signature packet */ /* find the correct signature packet */
for( node=keyblock; node; node = node->next ) { for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID ) { if( node->pkt->pkttype == PKT_USER_ID ) {
@ -1707,8 +1753,8 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
} }
else if( state && node->pkt->pkttype == PKT_SIGNATURE ) { else if( state && node->pkt->pkttype == PKT_SIGNATURE ) {
sigpkt = node->pkt->pkt.signature; sigpkt = node->pkt->pkt.signature;
if( sigpkt->keyid[0] == keyid[0] if( sigpkt->keyid[0] == sigkid[0]
&& sigpkt->keyid[1] == keyid[1] && sigpkt->keyid[1] == sigkid[1]
&& (sigpkt->sig_class&~3) == 0x10 ) && (sigpkt->sig_class&~3) == 0x10 )
break; /* found */ break; /* found */
} }
@ -1723,23 +1769,28 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
rc = check_key_signature( keyblock, node, &is_selfsig ); rc = check_key_signature( keyblock, node, &is_selfsig );
if( is_selfsig ) { if( is_selfsig ) {
log_error(_("lid %lu: self-signature in hintlist\n"), lid ); log_error(_("lid %lu: self-signature in hintlist\n"), lid );
return ; return;
} }
if( !rc ) { /* valid signature */ if( !rc ) { /* valid signature */
if( opt.verbose )
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"good signature (3)\n"),
(ulong)keyid[1], lid, uhash[18], uhash[19],
(ulong)sigpkt->keyid[1] );
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID; sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED | SIGF_VALID;
} }
else if( rc == G10ERR_NO_PUBKEY ) { else if( rc == G10ERR_NO_PUBKEY ) {
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"very strange: no public key for signature %08lX\n"), "very strange: no public key\n"),
(ulong)keyid[1], lid, uhash[18], uhash[19], (ulong)keyid[1], lid, uhash[18], uhash[19],
(ulong)sigpkt->keyid[1] ); (ulong)sigpkt->keyid[1] );
sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY; sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
} }
else { else {
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"invalid signature: %s\n"), "invalid signature: %s\n"),
(ulong)keyid[1], lid, (ulong)keyid[1], lid, uhash[18], uhash[19],
uhash[18], uhash[19], g10_errstr(rc)); (ulong)sigpkt->keyid[1], g10_errstr(rc) );
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED; sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
} }
sigrec->dirty = 1; sigrec->dirty = 1;
@ -1930,7 +1981,7 @@ upd_uid_record( PKT_user_id *uid, TRUSTREC *drec, RECNO_LIST *recno_list,
static void static void
upd_pref_record( PKT_signature *sig, TRUSTREC *drec, upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
u32 *keyid, ulong *uidrecno, byte *uidhash ) u32 *keyid, TRUSTREC *urec, byte *uidhash )
{ {
static struct { static struct {
sigsubpkttype_t subpkttype; sigsubpkttype_t subpkttype;
@ -1941,7 +1992,7 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR }, { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
{ 0, 0 } { 0, 0 }
}; };
TRUSTREC urec, prec; TRUSTREC prec;
const byte *s; const byte *s;
size_t n; size_t n;
int k, i; int k, i;
@ -1949,13 +2000,10 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
int recno_idx = 0; int recno_idx = 0;
ulong recno; ulong recno;
/* we need the uid record */
read_record( *uidrecno, &urec, RECTYPE_UID );
/* First delete all pref records /* First delete all pref records
* This is much simpler than checking whether we have to * This is much simpler than checking whether we have to
* do update the record at all - the record cache may care about it */ * do update the record at all - the record cache may care about it */
for( recno=urec.r.uid.prefrec; recno; recno = prec.r.pref.next ) { for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
read_record( recno, &prec, RECTYPE_PREF ); read_record( recno, &prec, RECTYPE_PREF );
delete_record( recno ); delete_record( recno );
} }
@ -1999,8 +2047,8 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
write_record( &prec ); write_record( &prec );
} }
/* don't need to write the last one, but update the uid */ /* don't need to write the last one, but update the uid */
urec.r.uid.prefrec = recno_idx? recno_tbl[0] : 0; urec->r.uid.prefrec = recno_idx? recno_tbl[0] : 0;
write_record( &urec ); urec->dirty = 1;
} }
@ -2014,25 +2062,41 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
u32 *keyid, ulong *uidrecno, byte *uidhash, u32 *keyid, ulong *uidrecno, byte *uidhash,
KBNODE keyblock, KBNODE signode ) KBNODE keyblock, KBNODE signode )
{ {
TRUSTREC urec;
int rc; int rc;
ulong lid = drec->recnum; ulong lid = drec->recnum;
if( !*uidrecno ) {
/* fixme: handle direct key signatures */
log_error("key %08lX: signature without user id\n", (ulong)keyid[1] );
return;
}
read_record( *uidrecno, &urec, RECTYPE_UID );
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
if( (sig->sig_class&~3) == 0x10 ) { if( (sig->sig_class&~3) == 0x10 ) {
/* must verify this selfsignature here, so that we can /* must verify this selfsignature here, so that we can
* build the preference record and validate the uid record * build the preference record and validate the uid record
*/ */
if( !*uidrecno ) { if( !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
log_error("key %08lX: self-signature without user id\n", rc = check_key_signature( keyblock, signode, NULL );
(ulong)keyid[1] ); if( !rc ) {
if( opt.verbose )
log_info(_(
"key %08lX.%lu, uid %02X%02X: "
"good self-signature\n"),
(ulong)keyid[1], lid, uidhash[18],
uidhash[19] );
upd_pref_record( sig, drec, keyid, &urec, uidhash );
urec.r.uid.uidflags = UIDF_CHECKED | UIDF_VALID;
} }
else if( (rc = check_key_signature( keyblock, signode, NULL ))) { else {
log_error("key %08lX, uid %02X%02X: " log_error("key %08lX, uid %02X%02X: "
"invalid self-signature: %s\n", (ulong)keyid[1], "invalid self-signature: %s\n", (ulong)keyid[1],
uidhash[18], uidhash[19], g10_errstr(rc) ); uidhash[18], uidhash[19], g10_errstr(rc) );
urec.r.uid.uidflags = UIDF_CHECKED;
} }
else { /* valid sig (may be revoked, but that doesn't matter here) */ urec.dirty = 1;
upd_pref_record( sig, drec, keyid, uidrecno, uidhash );
} }
} }
else {/* is revocation sig etc */ else {/* is revocation sig etc */
@ -2051,18 +2115,43 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
* be converted to a dir record as soon as a new public key is * be converted to a dir record as soon as a new public key is
* inserted into the trustdb. * inserted into the trustdb.
*/ */
TRUSTREC urec, rec; TRUSTREC rec;
ulong recno; ulong recno;
TRUSTREC delrec; TRUSTREC delrec;
int delrecidx; int delrecidx;
int newflag = 0; int newflag = 0;
ulong newlid = 0; ulong newlid = 0;
PKT_public_key *pk = m_alloc_clear( sizeof *pk ); PKT_public_key *pk = m_alloc_clear( sizeof *pk );
ulong pk_lid = 0;
int found_sig = 0;
int found_delrec = 0;
delrec.recnum = 0; delrec.recnum = 0;
/* we need the uid record */
read_record( *uidrecno, &urec, RECTYPE_UID );
rc = get_pubkey( pk, sig->keyid );
if( !rc ) {
if( pk->local_id )
pk_lid = pk->local_id;
else {
rc = tdbio_search_dir_bypk( pk, &rec );
if( !rc )
pk_lid = rec.recnum;
else if( rc == -1 ) { /* see whether there is a sdir instead */
u32 akid[2];
keyid_from_pk( pk, akid );
rc = tdbio_search_sdir( akid, pk->pubkey_algo, &rec );
if( !rc )
pk_lid = rec.recnum;
}
}
}
free_public_key( pk ); pk = NULL;
/* Loop over all signatures just in case one is not correctly
* marked. If we see the correct signature, set a flag.
* delete duplicate signatures (should not happen but...)
*/
for( recno = urec.r.uid.siglist; recno; recno = rec.r.sig.next ) { for( recno = urec.r.uid.siglist; recno; recno = rec.r.sig.next ) {
int i; int i;
@ -2070,12 +2159,25 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
for(i=0; i < SIGS_PER_RECORD; i++ ) { for(i=0; i < SIGS_PER_RECORD; i++ ) {
TRUSTREC tmp; TRUSTREC tmp;
if( !rec.r.sig.sig[i].lid ) { if( !rec.r.sig.sig[i].lid ) {
if( !delrec.recnum ) { if( !found_delrec && !delrec.recnum ) {
delrec = rec; delrec = rec;
delrecidx = i; delrecidx = i;
found_delrec=1;
} }
continue; /* skip deleted sigs */ continue; /* skip deleted sigs */
} }
if( rec.r.sig.sig[i].lid == pk_lid ) {
if( found_sig ) {
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"duplicated signature - deleted\n"),
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1] );
rec.r.sig.sig[i].lid = 0;
rec.dirty = 1;
}
else
found_sig = 1;
}
if( rec.r.sig.sig[i].flag & SIGF_CHECKED ) if( rec.r.sig.sig[i].flag & SIGF_CHECKED )
continue; /* we already checked this signature */ continue; /* we already checked this signature */
if( rec.r.sig.sig[i].flag & SIGF_NOPUBKEY ) if( rec.r.sig.sig[i].flag & SIGF_NOPUBKEY )
@ -2087,24 +2189,30 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
* the signature: */ * the signature: */
rc = check_key_signature( keyblock, signode, NULL ); rc = check_key_signature( keyblock, signode, NULL );
if( !rc ) { /* valid signature */ if( !rc ) { /* valid signature */
if( opt.verbose )
log_info(_(
"key %08lX.%lu, uid %02X%02X, sig %08lX: "
"good signature (1)\n"),
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1] );
rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID; rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
} }
else if( rc == G10ERR_NO_PUBKEY ) { else if( rc == G10ERR_NO_PUBKEY ) {
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"weird: no public key for signature %08lX\n"), "weird: no public key\n"),
(ulong)keyid[1], lid, uidhash[18], (ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1] ); uidhash[19], (ulong)sig->keyid[1] );
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY; rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
} }
else { else {
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"invalid signature: %s\n"), "invalid signature: %s\n"),
(ulong)keyid[1], lid, (ulong)keyid[1], lid, uidhash[18],
uidhash[18], uidhash[19], g10_errstr(rc)); uidhash[19], (ulong)sig->keyid[1],
g10_errstr(rc));
rec.r.sig.sig[i].flag = SIGF_CHECKED; rec.r.sig.sig[i].flag = SIGF_CHECKED;
} }
write_record( &rec ); rec.dirty = 1;
goto ready;
} }
else if( tmp.rectype == RECTYPE_SDIR ) { else if( tmp.rectype == RECTYPE_SDIR ) {
/* must check that it is the right one */ /* must check that it is the right one */
@ -2117,11 +2225,10 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
(ulong)keyid[1], lid, (ulong)keyid[1], lid,
uidhash[18], uidhash[19], tmp.recnum ); uidhash[18], uidhash[19], tmp.recnum );
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY; rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
write_record( &rec ); rec.dirty = 1;
/* fixme: should we verify that the record is /* fixme: should we verify that the record is
* in the hintlist? - This case here should anyway * in the hintlist? - This case here should anyway
* never occur */ * never occur */
goto ready;
} }
} }
else { else {
@ -2130,48 +2237,52 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
die_invalid_db(); die_invalid_db();
} }
} }
if( found_delrec && delrec.recnum ) {
delrec = rec;
found_delrec = 0; /* we onyl want the first one */
} }
if( rec.dirty )
write_record( &rec );
}
if( found_sig )
goto leave;
/* at this point, we have verified, that the signature is not in /* at this point, we have verified, that the signature is not in
* our list of signatures. Add a new record with that signature * our list of signatures. Add a new record with that signature
* and if the public key is there, check the signature. */ * and if the public key is there, check the signature. */
rc = get_pubkey( pk, sig->keyid );
if( !rc ) { if( !pk_lid )
/* check that we already have the record in the trustdb;
* if not we should not check the signature, because we do
* not have the lid of the signature and therefore can't add
* a signature record. We will fake a no_pubkey error, so
* that this is handled, like we do not have the publick key at
* at all. The alternative would be a recursive insert of
* records - but that is not good.
*/
rc = query_trust_record( pk );
if( rc == -1 )
rc = G10ERR_NO_PUBKEY; rc = G10ERR_NO_PUBKEY;
else else
rc = check_key_signature( keyblock, signode, NULL ); rc = check_key_signature( keyblock, signode, NULL );
}
if( !rc ) { /* valid signature */ if( !rc ) { /* valid signature */
newlid = pk->local_id; /* this is the pk of the signature */ if( opt.verbose )
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"good signature (2)\n"),
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1] );
newlid = pk_lid; /* this is the pk of the signature */
if( !newlid ) if( !newlid )
BUG(); BUG();
newflag = SIGF_CHECKED | SIGF_VALID; newflag = SIGF_CHECKED | SIGF_VALID;
} }
else if( rc == G10ERR_NO_PUBKEY ) { else if( rc == G10ERR_NO_PUBKEY ) {
if( opt.verbose ) if( opt.verbose > 1 )
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"no public key for signature %08lX\n"), "no public key\n"),
(ulong)keyid[1], lid, uidhash[18], (ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1] ); uidhash[19], (ulong)sig->keyid[1] );
newflag = SIGF_NOPUBKEY; newflag = SIGF_NOPUBKEY;
} }
else { else {
log_info(_("key %08lX.%lu, uid %02X%02X: " log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
"invalid signature: %s\n"), "invalid signature: %s\n"),
(ulong)keyid[1], lid, uidhash[18], uidhash[19], (ulong)keyid[1], lid, uidhash[18], uidhash[19],
g10_errstr(rc)); (ulong)sig->keyid[1], g10_errstr(rc));
newflag = SIGF_CHECKED; newflag = SIGF_CHECKED;
} }
free_public_key( pk );
if( !newlid ) { /* create a shadow dir record */ if( !newlid ) { /* create a shadow dir record */
TRUSTREC sdir, hlst, tmphlst; TRUSTREC sdir, hlst, tmphlst;
@ -2250,16 +2361,17 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
tmp.r.sig.sig[0].flag= newflag; tmp.r.sig.sig[0].flag= newflag;
write_record( &tmp ); write_record( &tmp );
urec.r.uid.siglist = tmp.recnum; urec.r.uid.siglist = tmp.recnum;
write_record( &urec ); urec.dirty = 1;
} }
ready:
;
} }
else { else {
/* handle other sig classes */ /* handle other sig classes */
} }
leave:
if( urec.dirty )
write_record( &urec );
} }
@ -2389,7 +2501,7 @@ update_trust_record( KBNODE keyblock )
else if( drec.dirty ) { else if( drec.dirty ) {
drec.r.dir.dirflags &= ~DIRF_CHECKED; /* reset flag */ drec.r.dir.dirflags &= ~DIRF_CHECKED; /* reset flag */
write_record( &drec ); write_record( &drec );
/* fixme: commit_transaction */ do_sync();
} }
rel_recno_list( &recno_list ); rel_recno_list( &recno_list );
return rc; return rc;
@ -2437,9 +2549,17 @@ insert_trust_record( PKT_public_key *pk )
/* check that we used the primary key (we are little bit paranoid) */ /* check that we used the primary key (we are little bit paranoid) */
{ PKT_public_key *a_pk; { PKT_public_key *a_pk;
u32 akid[2], bkid[2];
node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
a_pk = node->pkt->pkt.public_key; a_pk = node->pkt->pkt.public_key;
if( cmp_public_keys( a_pk, pk ) ) {
/* we can't use cmp_public_keys here because some parts (expiredate)
* might not be set in pk <--- but why (fixme) */
keyid_from_pk( a_pk, akid );
keyid_from_pk( pk, bkid );
if( akid[0] != bkid[0] || akid[1] != bkid[1] ) {
log_error("did not use primary key for insert_trust_record()\n"); log_error("did not use primary key for insert_trust_record()\n");
rc = G10ERR_GENERAL; rc = G10ERR_GENERAL;
goto leave; goto leave;
@ -2492,6 +2612,7 @@ insert_trust_record( PKT_public_key *pk )
if( rc && hintlist ) if( rc && hintlist )
; /* fixme: the hintlist is not anymore anchored */ ; /* fixme: the hintlist is not anymore anchored */
release_kbnode( keyblock ); release_kbnode( keyblock );
do_sync();
return rc; return rc;
} }
@ -2504,6 +2625,7 @@ update_ownertrust( ulong lid, unsigned new_trust )
read_record( lid, &rec, RECTYPE_DIR ); read_record( lid, &rec, RECTYPE_DIR );
rec.r.dir.ownertrust = new_trust; rec.r.dir.ownertrust = new_trust;
write_record( &rec ); write_record( &rec );
do_sync();
return 0; return 0;
} }

View File

@ -46,6 +46,7 @@ void list_trust_path( int max_depth, const char *username );
void export_ownertrust(void); void export_ownertrust(void);
void import_ownertrust(const char *fname); void import_ownertrust(const char *fname);
void check_trustdb( const char *username ); void check_trustdb( const char *username );
void update_trustdb( void );
int init_trustdb( int level, const char *dbname ); int init_trustdb( int level, const char *dbname );
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel ); int check_trust( PKT_public_key *pk, unsigned *r_trustlevel );
int query_trust_info( PKT_public_key *pk ); int query_trust_info( PKT_public_key *pk );

View File

@ -1,3 +1,8 @@
Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.h (iobuf_get): Now uses .nofast
(iobuf_get2): Removed.
Mon Sep 14 09:17:22 1998 Werner Koch (wk@(none)) Mon Sep 14 09:17:22 1998 Werner Koch (wk@(none))
* util.h (HAVE_ATEXIT): New. * util.h (HAVE_ATEXIT): New.

View File

@ -97,7 +97,7 @@ int g10c_debug_mode;
int g10_opt_verbose; int g10_opt_verbose;
/*-- dynload.c --*/ /*-- dynload.c --*/
void register_cipher_extension( const char *fname ); void register_cipher_extension( const char *mainpgm, const char *fname );
/*-- md.c --*/ /*-- md.c --*/
int string_to_digest_algo( const char *string ); int string_to_digest_algo( const char *string );

View File

@ -41,6 +41,8 @@ struct iobuf_struct {
unsigned long nlimit; unsigned long nlimit;
unsigned long nbytes; /* used together with nlimit */ unsigned long nbytes; /* used together with nlimit */
unsigned long ntotal; /* total bytes read (position of stream) */ unsigned long ntotal; /* total bytes read (position of stream) */
int nofast; /* used by the iobuf_get() */
void *directfp;
struct { struct {
size_t size; /* allocated size */ size_t size; /* allocated size */
size_t start; /* number of invalid bytes at the begin of the buffer */ size_t start; /* number of invalid bytes at the begin of the buffer */
@ -70,6 +72,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_open( const char *fname ); IOBUF iobuf_open( const char *fname );
IOBUF iobuf_fopen( const char *fname, const char *mode );
IOBUF iobuf_create( const char *fname ); IOBUF iobuf_create( const char *fname );
IOBUF iobuf_append( const char *fname ); IOBUF iobuf_append( const char *fname );
IOBUF iobuf_openrw( const char *fname ); IOBUF iobuf_openrw( const char *fname );
@ -114,15 +117,10 @@ int iobuf_in_block_mode( IOBUF a );
* returned value to be in the range 0 ..255. * returned value to be in the range 0 ..255.
*/ */
#define iobuf_get(a) \ #define iobuf_get(a) \
( ((a)->nlimit || (a)->d.start >= (a)->d.len )? \ ( ((a)->nofast || (a)->d.start >= (a)->d.len )? \
iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) ) iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) )
#define iobuf_get_noeof(a) (iobuf_get((a))&0xff) #define iobuf_get_noeof(a) (iobuf_get((a))&0xff)
/* use this if you have ungetted stuff */
#define iobuf_get2(a) \
( ( (a)->unget.buf || (a)->nlimit || (a)->d.start >= (a)->d.len )? \
iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) )
/* write a byte to the iobuf and return true on write error /* write a byte to the iobuf and return true on write error
* This macro does only write the low order byte * This macro does only write the low order byte
*/ */

View File

@ -1,3 +1,7 @@
Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
* config-links (freebsd): ELF patches from Jun Kuriyama.
Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de) Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free). * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).

View File

@ -10,6 +10,16 @@ test -d ./mpi || mkdir ./mpi
echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
case "${target}" in case "${target}" in
i[34]86*-*-freebsd*-elf)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i[56]86*-*-freebsd*-elf)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
;;
i[34]86*-*-linuxaout* | i[34]86*-*-linuxoldld* | i[34]86*-*-*bsd*) i[34]86*-*-linuxaout* | i[34]86*-*-linuxoldld* | i[34]86*-*-*bsd*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
@ -122,7 +132,7 @@ case "${target}" in
*-*-linuxaout* | *-*-linuxoldld* | *-*-linux-gnuoldld*) *-*-linuxaout* | *-*-linuxoldld* | *-*-linux-gnuoldld*)
needs_underscore="y" needs_underscore="y"
;; ;;
*-*-linux* | *-sysv* | *-solaris* | *-gnu*) *-*-linux* | *-sysv* | *-solaris* | *-gnu* | *-freebsd*-elf)
needs_underscore="n" needs_underscore="n"
;; ;;
*) *)

5
scripts/ChangeLog Normal file
View File

@ -0,0 +1,5 @@
Wed Oct 14 09:55:25 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.guess (FreeBSD): Changes from Jun Kuriyama to support ELF
* config.sub: (freebsd): Add to maybe_os

12
scripts/config.guess vendored
View File

@ -409,7 +409,17 @@ EOF
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
*:FreeBSD:*:*) *:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` rel_number=`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//' 2>/dev/null`
if test "$rel_number" = "3.0"; then
ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string"|grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then
echo ${UNAME_MACHINE}-unknown-freebsd${rel_number}-elf
else
echo ${UNAME_MACHINE}-unknown-freebsd${rel_number}-aout
fi
else
echo ${UNAME_MACHINE}-unknown-freebsd${rel_number}
fi
exit 0 ;; exit 0 ;;
*:NetBSD:*:*) *:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`

2
scripts/config.sub vendored
View File

@ -68,7 +68,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations. # Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in case $maybe_os in
linux-gnu*) linux-gnu*|freebsd*-*)
os=-$maybe_os os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;; ;;

View File

@ -5,3 +5,4 @@ mkinstalldirs
mkdiff mkdiff
missing missing
gnupg.spec gnupg.spec
ChangeLog

View File

@ -1,3 +1,7 @@
Tue Oct 13 12:40:13 1998 Werner Koch (wk@isil.d.shuttle.de)
* util.c (.nofast): set this variable
Wed Oct 7 19:27:50 1998 Werner Koch (wk@isil.d.shuttle.de) Wed Oct 7 19:27:50 1998 Werner Koch (wk@isil.d.shuttle.de)
* memory.c (m_print_stats): New. * memory.c (m_print_stats): New.

View File

@ -431,6 +431,13 @@ iobuf_close( IOBUF a )
size_t dummy_len; size_t dummy_len;
int rc=0; int rc=0;
if( a->directfp ) {
fclose( a->directfp );
if( DBG_IOBUF )
log_debug("iobuf-close -> %p\n", a->directfp );
return 0;
}
for( ; a && !rc ; a = a2 ) { for( ; a && !rc ; a = a2 ) {
a2 = a->chain; a2 = a->chain;
if( a->usage == 2 && (rc=iobuf_flush(a)) ) if( a->usage == 2 && (rc=iobuf_flush(a)) )
@ -602,6 +609,39 @@ iobuf_openrw( const char *fname )
return a; return a;
} }
/****************
* You can overwrite the normal iobuf behaviour by using this function.
* If used, the crwated iobuf is a simple wrapper around stdio.
* NULL if an error occures and sets errno
*/
IOBUF
iobuf_fopen( const char *fname, const char *mode )
{
IOBUF a;
FILE *fp;
int print_only = 0;
if( !fname || (*fname=='-' && !fname[1]) ) {
fp = stdin; /* fixme: set binary mode for msdoze */
fname = "[stdin]";
print_only = 1;
}
else if( !(fp = fopen(fname, mode) ) )
return NULL;
a = iobuf_alloc(1, 8192 );
a->directfp = fp;
if( DBG_IOBUF )
log_debug("iobuf_fopen -> %p\n", a->directfp );
return a;
}
/**************** /****************
* Register an i/o filter. * Register an i/o filter.
*/ */
@ -614,6 +654,9 @@ iobuf_push_filter( IOBUF a,
size_t dummy_len=0; size_t dummy_len=0;
int rc=0; int rc=0;
if( a->directfp )
BUG();
if( a->usage == 2 && (rc=iobuf_flush(a)) ) if( a->usage == 2 && (rc=iobuf_flush(a)) )
return rc; return rc;
/* make a copy of the current stream, so that /* make a copy of the current stream, so that
@ -640,6 +683,7 @@ iobuf_push_filter( IOBUF a,
/* disable nlimit for the new stream */ /* disable nlimit for the new stream */
a->ntotal = b->ntotal + b->nbytes; a->ntotal = b->ntotal + b->nbytes;
a->nlimit = a->nbytes = 0; a->nlimit = a->nbytes = 0;
a->nofast &= ~1;
/* make a link from the new stream to the original stream */ /* make a link from the new stream to the original stream */
a->chain = b; a->chain = b;
a->opaque = b->opaque; a->opaque = b->opaque;
@ -675,6 +719,9 @@ iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
size_t dummy_len=0; size_t dummy_len=0;
int rc=0; int rc=0;
if( a->directfp )
BUG();
if( DBG_IOBUF ) if( DBG_IOBUF )
log_debug("iobuf-%d.%d: pop '%s'\n", a->no, a->subno, a->desc ); log_debug("iobuf-%d.%d: pop '%s'\n", a->no, a->subno, a->desc );
if( !a->filter ) { /* this is simple */ if( !a->filter ) { /* this is simple */
@ -744,6 +791,7 @@ underflow(IOBUF a)
assert( a->d.start == a->d.len ); assert( a->d.start == a->d.len );
if( a->usage == 3 ) if( a->usage == 3 )
return -1; /* EOF because a temp buffer can't do an underflow */ return -1; /* EOF because a temp buffer can't do an underflow */
if( a->filter_eof ) { if( a->filter_eof ) {
if( DBG_IOBUF ) if( DBG_IOBUF )
log_debug("iobuf-%d.%d: filter eof\n", a->no, a->subno ); log_debug("iobuf-%d.%d: filter eof\n", a->no, a->subno );
@ -755,6 +803,22 @@ underflow(IOBUF a)
return -1; return -1;
} }
if( a->directfp ) {
FILE *fp = a->directfp;
len = fread( a->d.buf, 1, a->d.size, fp);
if( len < a->d.size ) {
if( ferror(fp) )
a->error = 1;
else if( feof( fp ) )
a->filter_eof = 1;
}
a->d.len = len;
a->d.start = 0;
return len? a->d.buf[a->d.start++] : -1;
}
if( a->filter ) { if( a->filter ) {
len = a->d.size; len = a->d.size;
rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain, rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
@ -790,6 +854,9 @@ underflow(IOBUF a)
void void
iobuf_clear_eof(IOBUF a) iobuf_clear_eof(IOBUF a)
{ {
if( a->directfp )
return;
assert(a->usage == 1); assert(a->usage == 1);
if( a->filter ) if( a->filter )
@ -806,6 +873,9 @@ iobuf_flush(IOBUF a)
size_t len; size_t len;
int rc; int rc;
if( a->directfp )
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 )
log_bug("temp buffer too short\n"); log_bug("temp buffer too short\n");
@ -842,6 +912,7 @@ iobuf_readbyte(IOBUF a)
return a->unget.buf[a->unget.start++]; return a->unget.buf[a->unget.start++];
m_free(a->unget.buf); m_free(a->unget.buf);
a->unget.buf = NULL; a->unget.buf = NULL;
a->nofast &= ~2;
} }
if( a->nlimit && a->nbytes >= a->nlimit ) if( a->nlimit && a->nbytes >= a->nlimit )
@ -924,6 +995,10 @@ iobuf_peek(IOBUF a, byte *buf, unsigned buflen )
int int
iobuf_writebyte(IOBUF a, unsigned c) iobuf_writebyte(IOBUF a, unsigned c)
{ {
if( a->directfp )
BUG();
if( a->d.len == a->d.size ) if( a->d.len == a->d.size )
if( iobuf_flush(a) ) if( iobuf_flush(a) )
return -1; return -1;
@ -937,6 +1012,10 @@ iobuf_writebyte(IOBUF a, unsigned c)
int int
iobuf_write(IOBUF a, byte *buf, unsigned buflen ) iobuf_write(IOBUF a, byte *buf, unsigned buflen )
{ {
if( a->directfp )
BUG();
do { do {
for( ; buflen && a->d.len < a->d.size; buflen--, buf++ ) for( ; buflen && a->d.len < a->d.size; buflen--, buf++ )
a->d.buf[a->d.len++] = *buf; a->d.buf[a->d.len++] = *buf;
@ -996,9 +1075,11 @@ iobuf_unget_and_close_temp( IOBUF a, IOBUF temp )
/* not yet cleaned up; do it now */ /* not yet cleaned up; do it now */
m_free(a->unget.buf); m_free(a->unget.buf);
a->unget.buf = NULL; a->unget.buf = NULL;
a->nofast &= ~2;
} }
a->unget.size = temp->d.len; a->unget.size = temp->d.len;
a->unget.buf = m_alloc( a->unget.size ); a->unget.buf = m_alloc( a->unget.size );
a->nofast |= 2;
a->unget.len = temp->d.len; a->unget.len = temp->d.len;
memcpy( a->unget.buf, temp->d.buf, a->unget.len ); memcpy( a->unget.buf, temp->d.buf, a->unget.len );
iobuf_close(temp); iobuf_close(temp);
@ -1012,6 +1093,10 @@ iobuf_unget_and_close_temp( IOBUF a, IOBUF temp )
void void
iobuf_set_limit( IOBUF a, unsigned long nlimit ) iobuf_set_limit( IOBUF a, unsigned long nlimit )
{ {
if( nlimit )
a->nofast |= 1;
else
a->nofast &= ~1;
a->nlimit = nlimit; a->nlimit = nlimit;
a->ntotal += a->nbytes; a->ntotal += a->nbytes;
a->nbytes = 0; a->nbytes = 0;
@ -1027,6 +1112,15 @@ iobuf_get_filelength( IOBUF a )
{ {
struct stat st; struct stat st;
if( a->directfp ) {
FILE *fp = a->directfp;
if( !fstat(fileno(fp), &st) )
return st.st_size;
log_error("fstat() failed: %s\n", strerror(errno) );
return 0;
}
for( ; a; a = a->chain ) for( ; a; a = a->chain )
if( !a->chain && a->filter == file_filter ) { if( !a->chain && a->filter == file_filter ) {
file_filter_ctx_t *b = a->filter_ov; file_filter_ctx_t *b = a->filter_ov;
@ -1061,6 +1155,15 @@ iobuf_seek( IOBUF a, ulong newpos )
{ {
file_filter_ctx_t *b = NULL; file_filter_ctx_t *b = NULL;
if( a->directfp ) {
FILE *fp = a->directfp;
if( fseek( fp, newpos, SEEK_SET ) ) {
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
return -1;
}
clearerr(fp);
}
else {
for( ; a; a = a->chain ) { for( ; a; a = a->chain ) {
if( !a->chain && a->filter == file_filter ) { if( !a->chain && a->filter == file_filter ) {
b = a->filter_ov; b = a->filter_ov;
@ -1069,22 +1172,22 @@ iobuf_seek( IOBUF a, ulong newpos )
} }
if( !a ) if( !a )
return -1; return -1;
if( fseek( b->fp, newpos, SEEK_SET ) ) { if( fseek( b->fp, newpos, SEEK_SET ) ) {
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) ); log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
return -1; return -1;
} }
}
a->d.len = 0; /* discard buffer */ a->d.len = 0; /* discard buffer */
a->d.start = 0; a->d.start = 0;
a->nbytes = 0; a->nbytes = 0;
a->nlimit = 0; a->nlimit = 0;
a->nofast &= ~1;
a->ntotal = newpos; a->ntotal = newpos;
a->error = 0; a->error = 0;
/* remove filters, but the last */ /* remove filters, but the last */
while( a->chain ) while( a->chain )
iobuf_pop_filter( a, a->filter, NULL ); iobuf_pop_filter( a, a->filter, NULL );
return 0; return 0;
} }