mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
last local commit
This commit is contained in:
parent
8477407e79
commit
e81e0970f7
@ -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)
|
||||
|
||||
* Makefile.am (g10defs.h): creates include file
|
||||
|
19
NEWS
19
NEWS
@ -2,6 +2,25 @@ Noteworthy changes in version 0.4.2
|
||||
-----------------------------------
|
||||
* 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
|
||||
-----------------------------------
|
||||
|
24
README
24
README
@ -1,4 +1,4 @@
|
||||
GNUPG - The GNU Privacy Guard
|
||||
GnuPG - The GNU Privacy Guard
|
||||
-------------------------------
|
||||
Version 0.4
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
|
||||
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
|
||||
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
|
||||
the "Global Trust Register for 1998", ISBN 0-9532397-0-5.
|
||||
|
||||
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>"
|
||||
"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>"
|
||||
"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
|
||||
_checked_that_it_is_really_my PGP2 key 0C9857A5, you can be sure
|
||||
that the above fingerprints are correct.
|
||||
@ -36,17 +36,17 @@
|
||||
|
||||
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
|
||||
IDEA (which is patented worldwide) and RSA (which is patented in
|
||||
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.
|
||||
|
||||
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 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
|
||||
and CAST5, Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
|
||||
|
||||
@ -230,7 +230,7 @@
|
||||
"#34"
|
||||
|
||||
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:
|
||||
@ -245,19 +245,19 @@
|
||||
|
||||
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
|
||||
passphrase; until we have a better solution (something like ssh-agent),
|
||||
you can use the option "--passhrase-fd n", which works like PGPs
|
||||
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.
|
||||
|
||||
|
||||
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
|
||||
stderr or the output of the fd specified with --status-fd to get detailed
|
||||
information about the errors.
|
||||
@ -269,7 +269,7 @@
|
||||
gpg --list-packets datafile
|
||||
|
||||
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.
|
||||
|
||||
gpgm --list-trustdb
|
||||
|
2
THANKS
2
THANKS
@ -26,12 +26,14 @@ Jean-loup Gailly gzip@prep.ai.mit.edu
|
||||
Jens Bachem bachem@rrz.uni-koeln.de
|
||||
John A. Martin jam@jamux.com
|
||||
Jörg Schilling schilling@fokus.gmd.de
|
||||
Jun Kuriyama kuriyama@sky.rim.or.jp
|
||||
Karl Fogel kfogel@guanabana.onshore.com
|
||||
Karsten Thygesen karthy@kom.auc.dk
|
||||
Kazu Yamamoto kazu@iijlab.net
|
||||
Lars Kellogg-Stedman lars@bu.edu
|
||||
Marco d'Itri md@linux.it
|
||||
Mark Adler madler@alumni.caltech.edu
|
||||
Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
|
||||
Martin Schulte schulte@thp.uni-koeln.de
|
||||
Matthew Skala mskala@ansuz.sooke.bc.ca
|
||||
Max Valianskiy maxcom@maxcom.ml.org
|
||||
|
57
TODO
57
TODO
@ -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.
|
||||
|
||||
* 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.
|
||||
it is ignored.
|
||||
|
||||
* Read more records at once in tdbio.c and provide a lazy write cache.
|
||||
|
||||
* 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.
|
||||
|
||||
* new menu to delete signatures and list signature in menu
|
||||
@ -33,10 +44,6 @@
|
||||
|
||||
* -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.
|
||||
|
||||
* 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
|
||||
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
|
||||
a backup system of only the secret part of the secret key.
|
||||
* add an option to re-create a public key from a secret key; we
|
||||
can do this in trustdb.c:verify_own_keys.
|
||||
|
||||
* OpenBSD has sometimes problems reading from /dev/random.
|
||||
|
||||
|
@ -71,6 +71,9 @@
|
||||
#undef USE_RAND_W32
|
||||
/* defined if we have a /dev/random and /dev/urandom */
|
||||
#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 HAVE_DL_DLOPEN
|
||||
|
@ -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>
|
||||
|
||||
* Makefile.am: fix sed -O substitutions to catch -O6, etc.
|
||||
|
@ -11,6 +11,8 @@ else
|
||||
pkglib_PROGRAMS =
|
||||
endif
|
||||
|
||||
DYNLINK_MOD_CFLAGS = @DYNLINK_MOD_CFLAGS@
|
||||
|
||||
|
||||
libcipher_a_SOURCES = cipher.c \
|
||||
pubkey.c \
|
||||
@ -48,11 +50,11 @@ EXTRA_twofish_SOURCES = twofish.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/' `
|
||||
|
||||
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]*/ /' `
|
||||
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_DL_DLOPEN
|
||||
#include <dlfcn.h>
|
||||
#elif defined(HAVE_DLD_DLD_LINK)
|
||||
#include <dld.h>
|
||||
#endif
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
@ -37,7 +39,11 @@
|
||||
|
||||
typedef struct ext_list {
|
||||
struct ext_list *next;
|
||||
#ifdef HAVE_DL_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 */
|
||||
void * (*enumfunc)(int, int*, int*, int*);
|
||||
char *hintstr; /* pointer into name */
|
||||
@ -53,6 +59,14 @@ typedef struct {
|
||||
void *sym;
|
||||
} 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
|
||||
* 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
|
||||
* loader may decide to only load a module which claims to have a
|
||||
* requested algorithm.
|
||||
*
|
||||
* mainpgm is the path to the program which wants to load a module
|
||||
* it is only used in some environments.
|
||||
*/
|
||||
void
|
||||
register_cipher_extension( const char *fname )
|
||||
register_cipher_extension( const char *mainpgm, const char *fname )
|
||||
{
|
||||
EXTLIST r, el;
|
||||
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 */
|
||||
char *p ;
|
||||
|
||||
@ -110,16 +131,22 @@ load_extension( EXTLIST el )
|
||||
{
|
||||
#ifdef USE_DYNAMIC_LINKING
|
||||
char **name;
|
||||
void *sym;
|
||||
#ifdef HAVE_DL_DLOPEN
|
||||
const char *err;
|
||||
int seq = 0;
|
||||
int class, vers;
|
||||
void *sym;
|
||||
#else
|
||||
unsigned long addr;
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
/* make sure we are not setuid */
|
||||
if( getuid() != geteuid() )
|
||||
log_bug("trying to load an extension while still setuid\n");
|
||||
|
||||
/* now that we are not setuid anymore, we can safely load modules */
|
||||
#ifdef HAVE_DL_DLOPEN
|
||||
el->handle = dlopen(el->name, RTLD_NOW);
|
||||
if( !el->handle ) {
|
||||
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 );
|
||||
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 )
|
||||
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? ")":"");
|
||||
|
||||
#ifdef HAVE_DL_DLOPEN
|
||||
sym = dlsym(el->handle, "gnupgext_enum_func");
|
||||
if( (err=dlerror()) ) {
|
||||
log_error("%s: invalid gnupg extension: %s\n", el->name, err );
|
||||
goto failure;
|
||||
}
|
||||
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 ) {
|
||||
/* list the contents of the module */
|
||||
while( (sym = (*el->enumfunc)(0, &seq, &class, &vers)) ) {
|
||||
@ -166,13 +243,16 @@ load_extension( EXTLIST el )
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
#ifdef HAVE_DL_DLOPEN
|
||||
if( el->handle ) {
|
||||
dlclose(el->handle);
|
||||
el->handle = NULL;
|
||||
}
|
||||
#endif
|
||||
el->failed = 1;
|
||||
#endif /*USE_DYNAMIC_LINKING*/
|
||||
return -1;
|
||||
|
@ -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
|
||||
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( fd_random == -1 )
|
||||
fd_random = open_device( "/dev/random", 8 );
|
||||
fd_random = open_device( NAME_OF_DEV_RANDOM, 8 );
|
||||
fd = fd_random;
|
||||
}
|
||||
else {
|
||||
if( fd_urandom == -1 )
|
||||
fd_urandom = open_device( "/dev/urandom", 9 );
|
||||
fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 );
|
||||
fd = fd_urandom;
|
||||
}
|
||||
do {
|
||||
|
25
configure.in
25
configure.in
@ -76,6 +76,7 @@ AC_PROG_INSTALL
|
||||
AM_CYGWIN32
|
||||
|
||||
|
||||
|
||||
case "${target}" in
|
||||
i386--mingw32)
|
||||
# special stuff for Windoze NT
|
||||
@ -104,6 +105,23 @@ case "${target}" in
|
||||
esac
|
||||
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.
|
||||
|
||||
|
||||
@ -126,12 +144,15 @@ fi
|
||||
else
|
||||
AC_MSG_CHECKING(for dynamic loading)
|
||||
DYNLINK_LDFLAGS=
|
||||
DYNLINK_MOD_CFLAGS=
|
||||
use_gnupg_extensions=no
|
||||
AC_MSG_RESULT(has been disabled)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes )
|
||||
AC_SUBST(DYNLINK_LDFLAGS)
|
||||
AC_SUBST(DYNLINK_MOD_CFLAGS)
|
||||
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
@ -182,7 +203,7 @@ fi
|
||||
dnl check whether we have a random device
|
||||
if test "$try_dev_random" = yes ; then
|
||||
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])
|
||||
if test "$ac_cv_have_dev_random" = yes; then
|
||||
AC_DEFINE(HAVE_DEV_RANDOM)
|
||||
@ -194,8 +215,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
dnl setup assembler stuff
|
||||
AC_MSG_CHECKING(for mpi assembler functions)
|
||||
if test -f $srcdir/mpi/config.links ; then
|
||||
|
@ -22,8 +22,7 @@ ssb::1536:20:5CE086B5B5A18FF4:1998-07-07:0:::
|
||||
20 = ElGamal (sign and encrypt)
|
||||
5. Field: KeyID
|
||||
6. Field: Creation Date (in UTC)
|
||||
7. Field: key expieres n days after creation.
|
||||
(I will change this to a key exiration date)
|
||||
7. Field: Key expiration date or empty if none.
|
||||
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
|
||||
deleted. May be later used to lookup the key: You will be
|
||||
|
@ -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)
|
||||
|
||||
* 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.
|
||||
|
||||
|
40
g10/armor.c
40
g10/armor.c
@ -109,7 +109,8 @@ static char *tail_strings[] = {
|
||||
static fhdr_state_t find_header( fhdr_state_t state,
|
||||
byte *buf, size_t *r_buflen,
|
||||
IOBUF a, size_t n,
|
||||
unsigned *r_empty, int *r_hashes );
|
||||
unsigned *r_empty, int *r_hashes,
|
||||
int only_keyblocks );
|
||||
|
||||
|
||||
static void
|
||||
@ -260,7 +261,8 @@ parse_hash_header( const char *line )
|
||||
*/
|
||||
static fhdr_state_t
|
||||
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;
|
||||
const char *s;
|
||||
@ -273,7 +275,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
|
||||
buflen = *r_buflen;
|
||||
assert(buflen >= 100 );
|
||||
buflen -= 3; /* reserved room for CR,LF and one extra */
|
||||
buflen -= 4; /* reserved room for CR,LF, and two extra */
|
||||
|
||||
do {
|
||||
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
|
||||
* or not */
|
||||
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;
|
||||
if( !n && c == '\n' )
|
||||
state = fhdrCHECKBegin;
|
||||
else if( !n || c == -1 )
|
||||
state = fhdrNOArmor; /* too short */
|
||||
else if( !is_armored( buf ) )
|
||||
else if( !is_armored( buf ) ) {
|
||||
state = fhdrNOArmor;
|
||||
if( c == '\n' )
|
||||
buf[n++] = c;
|
||||
}
|
||||
else if( c == '\n' )
|
||||
state = fhdrCHECKBegin;
|
||||
else
|
||||
@ -299,7 +304,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
n = 0;
|
||||
case fhdrINITCont: /* read more stuff into buffer */
|
||||
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;
|
||||
state = c == '\n' ? fhdrCHECKBegin :
|
||||
c == -1 ? fhdrEOF : fhdrINITSkip;
|
||||
@ -309,21 +314,21 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
if( c == '\n' )
|
||||
n = 0;
|
||||
else {
|
||||
while( (c=iobuf_get2(a)) != -1 && c != '\n' )
|
||||
while( (c=iobuf_get(a)) != -1 && c != '\n' )
|
||||
;
|
||||
}
|
||||
state = c == -1? fhdrEOF : fhdrINIT;
|
||||
break;
|
||||
|
||||
case fhdrSKIPHeader:
|
||||
while( (c=iobuf_get2(a)) != -1 && c != '\n' )
|
||||
while( (c=iobuf_get(a)) != -1 && c != '\n' )
|
||||
;
|
||||
state = c == -1? fhdrEOF : fhdrWAITHeader;
|
||||
break;
|
||||
|
||||
case fhdrWAITHeader: /* wait for Header lines */
|
||||
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] = 0;
|
||||
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) */
|
||||
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;
|
||||
if( n < buflen || c == '\n' ) {
|
||||
buf[n] = 0;
|
||||
@ -432,6 +437,9 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
break;
|
||||
if( !s )
|
||||
break; /* unknown begin line */
|
||||
if( only_keyblocks && i != 1 && i != 5 && i != 6 )
|
||||
break; /* not a keyblock armor */
|
||||
|
||||
/* found the begin line */
|
||||
hdr_line = i;
|
||||
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*/
|
||||
n = 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] = 0;
|
||||
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 */
|
||||
c = 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] = 0;
|
||||
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
|
||||
* mix of different white space characters */
|
||||
IOBUF b = iobuf_temp();
|
||||
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) {
|
||||
while( (c=iobuf_get(a)) != -1 && c != '\n' ) {
|
||||
iobuf_put(b,c);
|
||||
if( c != ' ' && c != '\t' && c != '\r' )
|
||||
break;
|
||||
@ -622,7 +630,8 @@ check_input( armor_filter_context_t *afx, IOBUF a )
|
||||
|
||||
n = DIM(afx->helpbuf);
|
||||
state = find_header( state, afx->helpbuf, &n, a,
|
||||
afx->helplen, &emplines, &afx->hashes);
|
||||
afx->helplen, &emplines, &afx->hashes,
|
||||
afx->only_keyblocks );
|
||||
switch( state ) {
|
||||
case fhdrNOArmor:
|
||||
afx->inp_checked = 1;
|
||||
@ -708,7 +717,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
|
||||
afx->helpidx = 0;
|
||||
state = find_header( state, afx->helpbuf, &n, a,
|
||||
state == fhdrNullClearsig? afx->helplen:0,
|
||||
&emplines, &afx->hashes );
|
||||
&emplines, &afx->hashes,
|
||||
afx->only_keyblocks );
|
||||
switch( state) {
|
||||
case fhdrERROR:
|
||||
invalid_armor();
|
||||
|
@ -209,8 +209,14 @@ do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
|
||||
else
|
||||
iobuf_put( a, pk->version );
|
||||
write_32(a, pk->timestamp );
|
||||
if( pk->version < 4 )
|
||||
write_16(a, pk->valid_days );
|
||||
if( pk->version < 4 ) {
|
||||
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 );
|
||||
n = pubkey_get_npkey( pk->pubkey_algo );
|
||||
if( !n )
|
||||
@ -280,8 +286,14 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
|
||||
else
|
||||
iobuf_put( a, sk->version );
|
||||
write_32(a, sk->timestamp );
|
||||
if( sk->version < 4 )
|
||||
write_16(a, sk->valid_days );
|
||||
if( sk->version < 4 ) {
|
||||
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 );
|
||||
nskey = pubkey_get_nskey( sk->pubkey_algo );
|
||||
npkey = pubkey_get_npkey( sk->pubkey_algo );
|
||||
|
@ -118,12 +118,14 @@ encode_simple( const char *filename, int mode )
|
||||
|
||||
if( opt.armor )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
else {
|
||||
write_comment( out, "#created by GNUPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")");
|
||||
if( opt.comment_string )
|
||||
write_comment( out, opt.comment_string );
|
||||
}
|
||||
#endif
|
||||
if( s2k && !opt.rfc1991 ) {
|
||||
PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc );
|
||||
enc->version = 4;
|
||||
@ -224,13 +226,14 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
|
||||
if( opt.armor )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
else {
|
||||
write_comment( out, "#created by GNUPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")");
|
||||
if( opt.comment_string )
|
||||
write_comment( out, opt.comment_string );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* create a session key */
|
||||
cfx.dek = m_alloc_secure( sizeof *cfx.dek );
|
||||
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
|
||||
|
22
g10/export.c
22
g10/export.c
@ -124,24 +124,10 @@ do_export( STRLIST users, int secret )
|
||||
|
||||
/* and write it */
|
||||
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
|
||||
if( opt.do_not_export_rsa ) {
|
||||
int algo;
|
||||
switch( node->pkt->pkttype ) {
|
||||
/* 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;
|
||||
}
|
||||
/* don't export any comment packets but those in the
|
||||
* secret keyring */
|
||||
if( !secret && node->pkt->pkttype == PKT_COMMENT )
|
||||
continue;
|
||||
if( (rc = build_packet( out, node->pkt )) ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
|
@ -31,6 +31,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
int status;
|
||||
int what;
|
||||
int only_keyblocks; /* skip all headers but ".... key block" */
|
||||
byte radbuf[4];
|
||||
int idx, idx2;
|
||||
u32 crc;
|
||||
|
@ -354,7 +354,7 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
|
||||
|
||||
if( a->timestamp != b->timestamp )
|
||||
return -1;
|
||||
if( a->valid_days != b->valid_days )
|
||||
if( a->expiredate != b->expiredate )
|
||||
return -1;
|
||||
if( a->pubkey_algo != b->pubkey_algo )
|
||||
return -1;
|
||||
@ -380,7 +380,7 @@ cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
|
||||
|
||||
if( pk->timestamp != sk->timestamp )
|
||||
return -1;
|
||||
if( pk->valid_days != sk->valid_days )
|
||||
if( pk->expiredate != sk->expiredate )
|
||||
return -1;
|
||||
if( pk->pubkey_algo != sk->pubkey_algo )
|
||||
return -1;
|
||||
|
45
g10/g10.c
45
g10/g10.c
@ -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.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
@ -88,6 +88,7 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
aPrintMD,
|
||||
aPrintMDs,
|
||||
aCheckTrustDB,
|
||||
aUpdateTrustDB,
|
||||
aFixTrustDB,
|
||||
aListTrustDB,
|
||||
aListTrustPath,
|
||||
@ -98,7 +99,6 @@ enum cmd_and_opt_values { aNull = 0,
|
||||
aGenRandom,
|
||||
|
||||
oFingerprint,
|
||||
oDoNotExportRSA,
|
||||
oAnswerYes,
|
||||
oAnswerNo,
|
||||
oKeyring,
|
||||
@ -172,13 +172,17 @@ static ARGPARSE_OPTS opts[] = {
|
||||
#endif
|
||||
{ aExport, "export" , 256, N_("export keys") },
|
||||
{ aExportSecret, "export-secret-keys" , 256, "@" },
|
||||
{ oDoNotExportRSA, "do-not-export-rsa", 0, "@" },
|
||||
{ aImport, "import", 256 , N_("import/merge keys")},
|
||||
{ aListPackets, "list-packets",256,N_("list only the sequence of packets")},
|
||||
#ifdef IS_G10MAINT
|
||||
{ aExportOwnerTrust, "export-ownertrust", 256, N_("export the ownertrust values")},
|
||||
{ aImportOwnerTrust, "import-ownertrust", 256 , N_("import ownertrust values")},
|
||||
{ aCheckTrustDB, "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
|
||||
{ aExportOwnerTrust,
|
||||
"export-ownertrust", 256, N_("export the ownertrust values")},
|
||||
{ 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")},
|
||||
{ aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
|
||||
{ aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
|
||||
@ -302,9 +306,9 @@ strusage( int level )
|
||||
switch( level ) {
|
||||
case 11: p =
|
||||
#ifdef IS_G10MAINT
|
||||
"gpgm (GNUPG)";
|
||||
"gpgm (GnuPG)";
|
||||
#else
|
||||
"gpg (GNUPG)";
|
||||
"gpg (GnuPG)";
|
||||
#endif
|
||||
break;
|
||||
case 13: p = VERSION; break;
|
||||
@ -323,7 +327,7 @@ strusage( int level )
|
||||
case 41: p =
|
||||
#ifdef IS_G10MAINT
|
||||
_("Syntax: gpgm [options] [files]\n"
|
||||
"GNUPG maintenance utility\n");
|
||||
"GnuPG maintenance utility\n");
|
||||
#else
|
||||
_("Syntax: gpg [options] [files]\n"
|
||||
"sign, check, encrypt or decrypt\n"
|
||||
@ -638,6 +642,7 @@ main( int argc, char **argv )
|
||||
case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
|
||||
case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
|
||||
case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
|
||||
case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
|
||||
case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
|
||||
case aListTrustPath: set_cmd( &cmd, aListTrustPath); 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 aListSecretKeys: set_cmd( &cmd, aListSecretKeys); 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 oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
|
||||
case oDoNotExportRSA: opt.do_not_export_rsa = 1; break;
|
||||
case oCompressSigs: opt.compress_sigs = 1; break;
|
||||
case oRunAsShmCP:
|
||||
#ifndef USE_SHM_COPROCESSING
|
||||
@ -835,13 +842,13 @@ main( int argc, char **argv )
|
||||
&& !(cmd == aKMode && argc == 2 ) ) {
|
||||
|
||||
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 )
|
||||
add_secret_keyring( sl->d );
|
||||
add_keyblock_resource( sl->d, 0, 1 );
|
||||
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 )
|
||||
add_keyring( sl->d );
|
||||
add_keyblock_resource( sl->d, 0, 0 );
|
||||
}
|
||||
FREE_STRLIST(nrings);
|
||||
FREE_STRLIST(sec_nrings);
|
||||
@ -996,7 +1003,7 @@ main( int argc, char **argv )
|
||||
else {
|
||||
/* add keyring (default keyrings are not registered in this
|
||||
* special case */
|
||||
add_keyring( argv[1] );
|
||||
add_keyblock_resource( argv[1], 0, 0 );
|
||||
public_key_list( **argv?1:0, argv );
|
||||
}
|
||||
}
|
||||
@ -1160,6 +1167,12 @@ main( int argc, char **argv )
|
||||
}
|
||||
break;
|
||||
|
||||
case aUpdateTrustDB:
|
||||
if( argc )
|
||||
wrong_args("--update-trustdb");
|
||||
update_trustdb();
|
||||
break;
|
||||
|
||||
case aCheckTrustDB:
|
||||
if( !argc )
|
||||
check_trustdb(NULL);
|
||||
|
157
g10/getkey.c
157
g10/getkey.c
@ -37,16 +37,15 @@
|
||||
#define MAX_PK_CACHE_ENTRIES 50
|
||||
#define MAX_UID_CACHE_ENTRIES 50
|
||||
|
||||
|
||||
typedef struct enum_seckey_context {
|
||||
int eof;
|
||||
STRLIST sl;
|
||||
IOBUF iobuf;
|
||||
} enum_seckey_context_t;
|
||||
static struct {
|
||||
int any;
|
||||
int okay_count;
|
||||
int nokey_count;
|
||||
int error_count;
|
||||
} lkup_stats[21];
|
||||
|
||||
|
||||
|
||||
static STRLIST keyrings;
|
||||
static STRLIST secret_keyrings;
|
||||
|
||||
#if MAX_UNK_CACHE_ENTRIES
|
||||
typedef struct keyid_list {
|
||||
@ -89,92 +88,24 @@ static int lookup( PKT_public_key *pk,
|
||||
static int lookup_sk( PKT_secret_key *sk,
|
||||
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
|
||||
* created if it does not exist.
|
||||
*/
|
||||
void
|
||||
add_keyring( const char *name )
|
||||
|
||||
|
||||
static void
|
||||
print_stats()
|
||||
{
|
||||
STRLIST sl;
|
||||
int rc, force = !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( &keyrings, p );
|
||||
m_free(p);
|
||||
int i;
|
||||
for(i=0; i < DIM(lkup_stats); i++ ) {
|
||||
if( lkup_stats[i].any )
|
||||
fprintf(stderr,
|
||||
"lookup stats: mode=%-2d ok=%-6d nokey=%-6d err=%-6d\n",
|
||||
i,
|
||||
lkup_stats[i].okay_count,
|
||||
lkup_stats[i].nokey_count,
|
||||
lkup_stats[i].error_count );
|
||||
}
|
||||
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
|
||||
cache_public_key( PKT_public_key *pk )
|
||||
@ -690,7 +621,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
|
||||
*/
|
||||
const byte *p;
|
||||
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 */
|
||||
break;
|
||||
}
|
||||
@ -739,12 +670,12 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
||||
const byte *p;
|
||||
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
|
||||
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. */
|
||||
pk = NULL; /* use only the first self signature */
|
||||
}
|
||||
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 */
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
* 2 = lookup by NAME (substring)
|
||||
* 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 */
|
||||
release_kbnode( keyblock );
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1107,12 +1056,19 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
|
||||
int rc=0;
|
||||
PACKET pkt;
|
||||
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 */
|
||||
c = m_alloc_clear( sizeof *c );
|
||||
*context = c;
|
||||
c->sl = secret_keyrings;
|
||||
c->sequence = 0;
|
||||
c->name = enum_keyblock_resources( &c->sequence, 1 );
|
||||
}
|
||||
|
||||
if( !sk ) { /* free the context */
|
||||
@ -1126,10 +1082,11 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
|
||||
if( c->eof )
|
||||
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 = iobuf_open( c->sl->d ) ) ) {
|
||||
log_error("enum_secret_keys: can't open '%s'\n", c->sl->d );
|
||||
if( !(c->iobuf = iobuf_open( c->name ) ) ) {
|
||||
log_error("enum_secret_keys: can't open '%s'\n", c->name );
|
||||
continue; /* try next file */
|
||||
}
|
||||
}
|
||||
@ -1165,7 +1122,7 @@ get_user_id_string( u32 *keyid )
|
||||
user_id_db_t r;
|
||||
char *p;
|
||||
int pass=0;
|
||||
/* try it two times; second pass reads from keyrings */
|
||||
/* try it two times; second pass reads from key resources */
|
||||
do {
|
||||
for(r=user_id_db; r; r = r->next )
|
||||
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;
|
||||
char *p;
|
||||
int pass=0;
|
||||
/* try it two times; second pass reads from keyrings */
|
||||
/* try it two times; second pass reads from key resources */
|
||||
do {
|
||||
for(r=user_id_db; r; r = r->next )
|
||||
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
|
||||
|
@ -96,6 +96,7 @@ import_keys( const char *fname )
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &cfx, 0, sizeof cfx);
|
||||
afx.only_keyblocks = 1;
|
||||
|
||||
/* open file */
|
||||
inp = iobuf_open(fname);
|
||||
|
@ -106,10 +106,6 @@ void set_next_passphrase( const char *s );
|
||||
char *get_last_passphrase(void);
|
||||
|
||||
/*-- 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_byname( PKT_public_key *pk, const char *name );
|
||||
int get_seckey( PKT_secret_key *sk, u32 *keyid );
|
||||
@ -156,7 +152,8 @@ int commit_kbnode( KBNODE *root );
|
||||
void dump_kbnode( KBNODE node );
|
||||
|
||||
/*-- 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 );
|
||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||
int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
|
||||
|
57
g10/keygen.c
57
g10/keygen.c
@ -58,8 +58,8 @@ add_key_expire( PKT_signature *sig, void *opaque )
|
||||
byte buf[8];
|
||||
u32 u;
|
||||
|
||||
if( sk->valid_days ) {
|
||||
u = sk->valid_days * 86400L;
|
||||
if( sk->expiredate ) {
|
||||
u = sk->expiredate;
|
||||
buf[0] = (u >> 24) & 0xff;
|
||||
buf[1] = (u >> 16) & 0xff;
|
||||
buf[2] = (u >> 8) & 0xff;
|
||||
@ -192,7 +192,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk )
|
||||
|
||||
static int
|
||||
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 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 );
|
||||
sk->timestamp = pk->timestamp = make_timestamp();
|
||||
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;
|
||||
pk->pkey[0] = mpi_copy( skey[0] );
|
||||
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
|
||||
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 i;
|
||||
@ -289,7 +291,9 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
pk = m_alloc_clear( sizeof *pk );
|
||||
sk->timestamp = pk->timestamp = make_timestamp();
|
||||
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;
|
||||
pk->pkey[0] = mpi_copy( skey[0] );
|
||||
pk->pkey[1] = mpi_copy( skey[1] );
|
||||
@ -477,11 +481,12 @@ ask_keysize( int algo )
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ask_valid_days()
|
||||
static u32
|
||||
ask_expiredate()
|
||||
{
|
||||
char *answer;
|
||||
int valid_days=0;
|
||||
u32 expiredate = 0;
|
||||
|
||||
tty_printf(_("Please specify how long the key should be valid.\n"
|
||||
" 0 = key does not expire\n"
|
||||
@ -513,12 +518,14 @@ ask_valid_days()
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !valid_days )
|
||||
if( !valid_days ) {
|
||||
tty_printf(_("Key does not expire at all\n"));
|
||||
expiredate = 0;
|
||||
}
|
||||
else {
|
||||
expiredate = make_timestamp() + valid_days * 86400L;
|
||||
/* print the date when the key expires */
|
||||
tty_printf(_("Key expires at %s\n"), strtimestamp(
|
||||
add_days_to_timestamp( make_timestamp(), valid_days )));
|
||||
tty_printf(_("Key expires at %s\n"), asctimestamp(expiredate) );
|
||||
}
|
||||
|
||||
if( !cpr_enabled()
|
||||
@ -527,7 +534,7 @@ ask_valid_days()
|
||||
break;
|
||||
}
|
||||
m_free(answer);
|
||||
return valid_days;
|
||||
return expiredate;
|
||||
}
|
||||
|
||||
|
||||
@ -713,7 +720,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
|
||||
|
||||
static int
|
||||
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 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 )
|
||||
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 )
|
||||
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
|
||||
BUG();
|
||||
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
if( !rc ) {
|
||||
add_kbnode( pub_root,
|
||||
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 " ("
|
||||
PRINTABLE_OS_NAME ")"));
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -781,7 +791,7 @@ generate_keypair()
|
||||
STRING2KEY *s2k;
|
||||
int rc;
|
||||
int algo;
|
||||
int ndays;
|
||||
u32 expiredate;
|
||||
int v4;
|
||||
int both = 0;
|
||||
|
||||
@ -797,7 +807,7 @@ generate_keypair()
|
||||
tty_printf(_("DSA keypair will have 1024 bits.\n"));
|
||||
}
|
||||
nbits = ask_keysize( algo );
|
||||
ndays = ask_valid_days();
|
||||
expiredate = ask_expiredate();
|
||||
uid = ask_user_id(0);
|
||||
if( !uid ) {
|
||||
log_error(_("Key generation cancelled.\n"));
|
||||
@ -824,10 +834,10 @@ generate_keypair()
|
||||
|
||||
if( both )
|
||||
rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root,
|
||||
dek, s2k, &sk, ndays, 1);
|
||||
dek, s2k, &sk, expiredate, 1);
|
||||
else
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, &sk, ndays, v4);
|
||||
dek, s2k, &sk, expiredate, v4);
|
||||
if( !rc )
|
||||
write_uid(pub_root, uid );
|
||||
if( !rc )
|
||||
@ -839,7 +849,7 @@ generate_keypair()
|
||||
|
||||
if( both ) {
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, NULL, ndays, 1 );
|
||||
dek, s2k, NULL, expiredate, 1 );
|
||||
if( !rc )
|
||||
rc = write_keybinding(pub_root, pub_root, sk);
|
||||
if( !rc )
|
||||
@ -927,7 +937,8 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
int okay=0, rc=0;
|
||||
KBNODE node;
|
||||
PKT_secret_key *sk = NULL; /* this is the primary sk */
|
||||
int v4, algo, ndays;
|
||||
int v4, algo;
|
||||
u32 expiredate;
|
||||
unsigned nbits;
|
||||
char *passphrase = NULL;
|
||||
DEK *dek = NULL;
|
||||
@ -964,7 +975,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
algo = ask_algo( &v4, 1 );
|
||||
assert(algo);
|
||||
nbits = ask_keysize( algo );
|
||||
ndays = ask_valid_days();
|
||||
expiredate = ask_expiredate();
|
||||
if( !cpr_enabled() && !cpr_get_answer_is_yes(N_("keygen.sub.okay"),
|
||||
_("Really create? ") ) )
|
||||
goto leave;
|
||||
@ -978,7 +989,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
||||
}
|
||||
|
||||
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
|
||||
dek, s2k, NULL, ndays, v4 );
|
||||
dek, s2k, NULL, expiredate, v4 );
|
||||
if( !rc )
|
||||
rc = write_keybinding(pub_keyblock, pub_keyblock, sk);
|
||||
if( !rc )
|
||||
|
17
g10/keyid.c
17
g10/keyid.c
@ -82,7 +82,12 @@ do_fingerprint_md( PKT_public_key *pk )
|
||||
md_putc( md, a );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
@ -108,7 +113,7 @@ do_fingerprint_md_sk( PKT_secret_key *sk )
|
||||
pk.pubkey_algo = sk->pubkey_algo;
|
||||
pk.version = sk->version;
|
||||
pk.timestamp = sk->timestamp;
|
||||
pk.valid_days = sk->valid_days;
|
||||
pk.expiredate = sk->expiredate;
|
||||
pk.pubkey_algo = sk->pubkey_algo;
|
||||
for( i=0; i < npkey; i++ )
|
||||
pk.pkey[i] = sk->skey[i];
|
||||
@ -303,9 +308,9 @@ expirestr_from_pk( PKT_public_key *pk )
|
||||
struct tm *tp;
|
||||
time_t atime;
|
||||
|
||||
if( !pk->valid_days )
|
||||
if( !pk->expiredate )
|
||||
return "never ";
|
||||
atime = add_days_to_timestamp( pk->timestamp, pk->valid_days );
|
||||
atime = pk->expiredate;
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
return buffer;
|
||||
@ -318,9 +323,9 @@ expirestr_from_sk( PKT_secret_key *sk )
|
||||
struct tm *tp;
|
||||
time_t atime;
|
||||
|
||||
if( !sk->valid_days )
|
||||
if( !sk->expiredate )
|
||||
return "never ";
|
||||
atime = add_days_to_timestamp( sk->timestamp, sk->valid_days );
|
||||
atime = sk->expiredate;
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
return buffer;
|
||||
|
@ -74,7 +74,8 @@ list_all( int secret )
|
||||
const char *s;
|
||||
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)) ) {
|
||||
log_error(_("can't open %s: %s\n"), s, strerror(errno));
|
||||
continue;
|
||||
@ -133,12 +134,12 @@ list_one( const char *name, int secret )
|
||||
sk = node->pkt->pkt.secret_key;
|
||||
keyid_from_sk( sk, keyid );
|
||||
if( opt.with_colons )
|
||||
printf("sec::%u:%d:%08lX%08lX:%s:%u:::",
|
||||
printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
|
||||
nbits_from_sk( sk ),
|
||||
sk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_sk( sk ),
|
||||
(unsigned)sk->valid_days
|
||||
sk->expiredate? strtimestamp(sk->expiredate):""
|
||||
/* fixme: add LID here */ );
|
||||
else
|
||||
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 );
|
||||
if( opt.with_colons ) {
|
||||
trustletter = query_trust_info( pk );
|
||||
printf("pub:%c:%u:%d:%08lX%08lX:%s:%u:",
|
||||
printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
|
||||
trustletter,
|
||||
nbits_from_pk( pk ),
|
||||
pk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_pk( pk ),
|
||||
(unsigned)pk->valid_days );
|
||||
pk->expiredate? strtimestamp(pk->expiredate):""
|
||||
);
|
||||
if( pk->local_id )
|
||||
printf("%lu", pk->local_id );
|
||||
putchar(':');
|
||||
@ -206,13 +208,13 @@ list_one( const char *name, int secret )
|
||||
|
||||
keyid_from_pk( pk2, keyid2 );
|
||||
if( opt.with_colons ) {
|
||||
printf("sub:%c:%u:%d:%08lX%08lX:%s:%u:",
|
||||
printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
|
||||
trustletter,
|
||||
nbits_from_pk( pk2 ),
|
||||
pk2->pubkey_algo,
|
||||
(ulong)keyid2[0],(ulong)keyid2[1],
|
||||
datestr_from_pk( pk2 ),
|
||||
(unsigned)pk2->valid_days
|
||||
pk2->expiredate? strtimestamp(pk2->expiredate):""
|
||||
/* fixme: add LID and ownertrust here */
|
||||
);
|
||||
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 );
|
||||
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 ),
|
||||
sk2->pubkey_algo,
|
||||
(ulong)keyid2[0],(ulong)keyid2[1],
|
||||
datestr_from_sk( sk2 ),
|
||||
(unsigned)sk2->valid_days
|
||||
sk2->expiredate? strtimestamp(sk2->expiredate):""
|
||||
/* fixme: add LID */
|
||||
);
|
||||
else
|
||||
|
@ -471,14 +471,14 @@ list_node( CTX c, KBNODE node )
|
||||
c->local_id = pk->local_id;
|
||||
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",
|
||||
c->trustletter,
|
||||
nbits_from_pk( pk ),
|
||||
pk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_pk( pk ),
|
||||
(unsigned)pk->valid_days );
|
||||
pk->expiredate? strtimestamp(pk->expiredate):"" );
|
||||
if( c->local_id )
|
||||
printf("%lu", c->local_id );
|
||||
putchar(':');
|
||||
@ -541,13 +541,13 @@ list_node( CTX c, KBNODE node )
|
||||
if( opt.with_colons ) {
|
||||
u32 keyid[2];
|
||||
keyid_from_sk( sk, keyid );
|
||||
printf("%s::%u:%d:%08lX%08lX:%s:%u:::",
|
||||
printf("%s::%u:%d:%08lX%08lX:%s:%s:::",
|
||||
mainkey? "sec":"ssb",
|
||||
nbits_from_sk( sk ),
|
||||
sk->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_sk( sk ),
|
||||
(unsigned)sk->valid_days
|
||||
sk->expiredate? strtimestamp(sk->expiredate):""
|
||||
/* fixme: add LID */ );
|
||||
}
|
||||
else
|
||||
|
@ -20,6 +20,10 @@
|
||||
#ifndef G10_OPTIONS_H
|
||||
#define G10_OPTIONS_H
|
||||
|
||||
|
||||
#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */
|
||||
|
||||
|
||||
struct {
|
||||
int verbose;
|
||||
unsigned debug;
|
||||
@ -37,7 +41,7 @@ struct {
|
||||
int no_armor;
|
||||
int list_packets; /* list-packets mode */
|
||||
int def_cipher_algo;
|
||||
int do_not_export_rsa;
|
||||
int reserved1;
|
||||
int def_digest_algo;
|
||||
int def_compress_algo;
|
||||
const char *def_secret_key;
|
||||
|
@ -111,7 +111,7 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
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 version;
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
@ -124,7 +124,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
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 version;
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
|
@ -917,8 +917,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
{
|
||||
int i, version, algorithm;
|
||||
unsigned n;
|
||||
unsigned long timestamp;
|
||||
unsigned short valid_period;
|
||||
unsigned long timestamp, expiredate;
|
||||
int npkey, nskey;
|
||||
int is_v4=0;
|
||||
int rc=0;
|
||||
@ -956,25 +955,30 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
|
||||
timestamp = read_32(inp); pktlen -= 4;
|
||||
if( is_v4 )
|
||||
valid_period = 0;
|
||||
expiredate = 0; /* have to get it from the selfsignature */
|
||||
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--;
|
||||
if( list_mode )
|
||||
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_SECRET_KEY? "secret" :
|
||||
pkttype == PKT_PUBLIC_SUBKEY? "public 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 ) {
|
||||
PKT_secret_key *sk = pkt->pkt.secret_key;
|
||||
|
||||
sk->timestamp = timestamp;
|
||||
sk->valid_days = valid_period;
|
||||
sk->expiredate = expiredate;
|
||||
sk->hdrbytes = hdrlen;
|
||||
sk->version = version;
|
||||
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;
|
||||
|
||||
pk->timestamp = timestamp;
|
||||
pk->valid_days = valid_period;
|
||||
pk->expiredate = expiredate;
|
||||
pk->hdrbytes = hdrlen;
|
||||
pk->version = version;
|
||||
pk->pubkey_algo = algorithm;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h> /* for truncate */
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "packet.h"
|
||||
@ -55,8 +56,8 @@
|
||||
#include "mpi.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
#include <unistd.h> /* for truncate */
|
||||
|
||||
|
||||
struct resource_table_struct {
|
||||
@ -96,30 +97,76 @@ check_pos( KBPOS *kbpos )
|
||||
****************** 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).
|
||||
* 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
|
||||
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;
|
||||
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++ )
|
||||
if( !resource_table[i].used )
|
||||
break;
|
||||
if( i == MAX_RESOURCES )
|
||||
return G10ERR_RESOURCE_LIMIT;
|
||||
if( i == MAX_RESOURCES ) {
|
||||
rc = G10ERR_RESOURCE_LIMIT;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
iobuf = iobuf_open( filename );
|
||||
if( !iobuf && !force )
|
||||
return G10ERR_OPEN_FILE;
|
||||
iobuf = iobuf_fopen( filename, "rb" );
|
||||
if( !iobuf && !force ) {
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( !iobuf ) {
|
||||
iobuf = iobuf_create( filename );
|
||||
if( !iobuf ) {
|
||||
log_error("%s: can't create: %s\n", filename, strerror(errno));
|
||||
return G10ERR_OPEN_FILE;
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
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].fname = m_strdup(filename);
|
||||
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 */
|
||||
kbpos->resno = i;
|
||||
rentry = check_pos( kbpos );
|
||||
kbpos->fp = iobuf_open( rentry->fname );
|
||||
kbpos->fp = iobuf_fopen( rentry->fname, "rb" );
|
||||
if( !kbpos->fp ) {
|
||||
log_error("can't open '%s'\n", rentry->fname );
|
||||
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;
|
||||
|
||||
if( req_sk->timestamp == sk->timestamp
|
||||
&& req_sk->valid_days == sk->valid_days
|
||||
&& req_sk->pubkey_algo == sk->pubkey_algo
|
||||
&& !cmp_seckey( req_sk, sk) )
|
||||
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;
|
||||
|
||||
if( req_pk->timestamp == pk->timestamp
|
||||
&& req_pk->valid_days == pk->valid_days
|
||||
&& req_pk->pubkey_algo == pk->pubkey_algo
|
||||
&& !cmp_pubkey( req_pk, pk ) )
|
||||
break; /* found */
|
||||
@ -572,7 +625,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
a = iobuf_open( rentry->fname );
|
||||
a = iobuf_fopen( rentry->fname, "rb" );
|
||||
if( !a ) {
|
||||
log_error("can't open '%s'\n", rentry->fname );
|
||||
return G10ERR_OPEN_FILE;
|
||||
@ -732,7 +785,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
BUG(); /* not allowed with such a handle */
|
||||
|
||||
/* open the source file */
|
||||
fp = iobuf_open( rentry->fname );
|
||||
fp = iobuf_fopen( rentry->fname, "rb" );
|
||||
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
|
||||
KBNODE kbctx, node;
|
||||
|
||||
|
@ -166,11 +166,9 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
|
||||
return G10ERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
if( pk->valid_days && add_days_to_timestamp(pk->timestamp,
|
||||
pk->valid_days) < cur_time ) {
|
||||
log_info(_("warning: signature key expired %s\n"), strtimestamp(
|
||||
add_days_to_timestamp(pk->timestamp,
|
||||
pk->valid_days)));
|
||||
if( pk->expiredate && pk->expiredate < cur_time ) {
|
||||
log_info(_("warning: signature key expired %s\n"),
|
||||
asctimestamp( pk->expiredate ) );
|
||||
write_status(STATUS_SIGEXPIRED);
|
||||
}
|
||||
|
||||
|
@ -225,12 +225,14 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
|
||||
if( opt.armor && !outfile )
|
||||
iobuf_push_filter( out, armor_filter, &afx );
|
||||
#ifdef ENABLE_COMMENT_PACKETS
|
||||
else {
|
||||
write_comment( out, "#created by GNUPG v" VERSION " ("
|
||||
PRINTABLE_OS_NAME ")");
|
||||
if( opt.comment_string )
|
||||
write_comment( out, opt.comment_string );
|
||||
}
|
||||
#endif
|
||||
if( encrypt ) {
|
||||
efx.pk_list = pk_list;
|
||||
/* fixme: set efx.cfx.datalen if known */
|
||||
|
344
g10/tdbio.c
344
g10/tdbio.c
@ -39,6 +39,27 @@
|
||||
#include "trustdb.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 */
|
||||
struct cmp_krec_fpr_struct {
|
||||
int pubkey_algo;
|
||||
@ -59,6 +80,184 @@ static int db_fd = -1;
|
||||
|
||||
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
|
||||
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.recnum = 0;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( !rc )
|
||||
tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( fname, _("failed to create version record: %s"),
|
||||
g10_errstr(rc));
|
||||
@ -185,7 +386,7 @@ create_hashtable( TRUSTREC *vr, int type )
|
||||
n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
|
||||
for(i=0; i < n; i++, recnum++ ) {
|
||||
memset( &rec, 0, sizeof rec );
|
||||
rec.rectype = RECTYPE_HTBL; /* free record */
|
||||
rec.rectype = RECTYPE_HTBL;
|
||||
rec.recnum = recnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
@ -194,6 +395,8 @@ create_hashtable( TRUSTREC *vr, int type )
|
||||
}
|
||||
/* update the version record */
|
||||
rc = tdbio_write_record( vr );
|
||||
if( !rc )
|
||||
rc = tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error updating version record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
@ -208,21 +411,21 @@ static ulong
|
||||
get_keyhashrec()
|
||||
{
|
||||
static ulong keyhashtbl; /* record number of the key hashtable */
|
||||
TRUSTREC vr;
|
||||
int rc;
|
||||
|
||||
if( keyhashtbl )
|
||||
return keyhashtbl;
|
||||
if( !keyhashtbl ) {
|
||||
TRUSTREC vr;
|
||||
int rc;
|
||||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
if( !vr.r.ver.keyhashtbl )
|
||||
create_hashtable( &vr, 0 );
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
if( !vr.r.ver.keyhashtbl )
|
||||
create_hashtable( &vr, 0 );
|
||||
|
||||
|
||||
return vr.r.ver.keyhashtbl;
|
||||
keyhashtbl = vr.r.ver.keyhashtbl;
|
||||
}
|
||||
return keyhashtbl;
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -233,20 +436,21 @@ static ulong
|
||||
get_sdirhashrec()
|
||||
{
|
||||
static ulong sdirhashtbl; /* record number of the hashtable */
|
||||
TRUSTREC vr;
|
||||
int rc;
|
||||
|
||||
if( sdirhashtbl )
|
||||
return sdirhashtbl;
|
||||
if( !sdirhashtbl ) {
|
||||
TRUSTREC vr;
|
||||
int rc;
|
||||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
if( !vr.r.ver.sdirhashtbl )
|
||||
create_hashtable( &vr, 1 );
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
if( !vr.r.ver.sdirhashtbl )
|
||||
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;
|
||||
rc = tdbio_read_record( item, &rec, 0 );
|
||||
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) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
if( rec.rectype == RECTYPE_HTBL ) {
|
||||
hashrec = item;
|
||||
level++;
|
||||
if( level >= keylen ) {
|
||||
log_error( db_name, "hashtable has invalid indirections.\n");
|
||||
log_error( "hashtable has invalid indirections.\n");
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
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,
|
||||
&rec, RECTYPE_HLST);
|
||||
if( rc ) {
|
||||
log_error( db_name,
|
||||
"scan keyhashtbl read hlst failed: %s\n",
|
||||
log_error( "scan keyhashtbl read hlst failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
@ -330,8 +534,7 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rec.r.hlst.rnum[i] = newrecnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error( db_name,
|
||||
"upd_hashtable: write hlst failed: %s\n",
|
||||
log_error( "upd_hashtable: write hlst failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
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,
|
||||
&rec, RECTYPE_HLST );
|
||||
if( rc ) {
|
||||
log_error( db_name,
|
||||
"upd_hashtable: read hlst failed: %s\n",
|
||||
log_error( "upd_hashtable: read hlst failed: %s\n",
|
||||
g10_errstr(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();
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc ) {
|
||||
log_error( db_name,
|
||||
"upd_hashtable: write hlst failed: %s\n",
|
||||
log_error( "upd_hashtable: write hlst failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
@ -361,14 +562,14 @@ upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
|
||||
rec.r.hlst.rnum[0] = newrecnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_error( db_name,
|
||||
"upd_hashtable: write ext hlst failed: %s\n",
|
||||
log_error( "upd_hashtable: write ext hlst failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
return rc; /* done */
|
||||
}
|
||||
} /* end loop over hlst slots */
|
||||
}
|
||||
else if( rec.rectype == RECTYPE_KEY
|
||||
|| rec.rectype == RECTYPE_DIR
|
||||
|| rec.rectype == RECTYPE_SDIR ) { /* insert a list record */
|
||||
if( rec.recnum == newrecnum ) {
|
||||
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 */
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc ) {
|
||||
log_error( db_name,
|
||||
"upd_hashtable: write new hlst failed: %s\n",
|
||||
log_error( "upd_hashtable: write new hlst failed: %s\n",
|
||||
g10_errstr(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;
|
||||
rc = tdbio_write_record( &lastrec );
|
||||
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) );
|
||||
return rc; /* ready */
|
||||
}
|
||||
else {
|
||||
log_error( db_name, "hashtbl %lu points to an invalid record\n",
|
||||
log_error( "hashtbl %lu points to an invalid record\n",
|
||||
item);
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
@ -637,23 +837,29 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
int
|
||||
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 n, i;
|
||||
|
||||
if( db_fd == -1 )
|
||||
open_db();
|
||||
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
|
||||
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
|
||||
return G10ERR_READ_FILE;
|
||||
}
|
||||
n = read( db_fd, buf, TRUST_RECORD_LEN);
|
||||
if( !n ) {
|
||||
return -1; /* eof */
|
||||
}
|
||||
else if( n != TRUST_RECORD_LEN ) {
|
||||
log_error(_("trustdb: read failed (n=%d): %s\n"), n, strerror(errno) );
|
||||
return G10ERR_READ_FILE;
|
||||
buf = get_record_from_cache( recnum );
|
||||
if( !buf ) {
|
||||
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
|
||||
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
|
||||
return G10ERR_READ_FILE;
|
||||
}
|
||||
n = read( db_fd, readbuf, TRUST_RECORD_LEN);
|
||||
if( !n ) {
|
||||
return -1; /* eof */
|
||||
}
|
||||
else if( n != TRUST_RECORD_LEN ) {
|
||||
log_error(_("trustdb: read failed (n=%d): %s\n"), n,
|
||||
strerror(errno) );
|
||||
return G10ERR_READ_FILE;
|
||||
}
|
||||
buf = readbuf;
|
||||
}
|
||||
rec->recnum = recnum;
|
||||
rec->dirty = 0;
|
||||
@ -791,14 +997,12 @@ tdbio_write_record( TRUSTREC *rec )
|
||||
{
|
||||
byte buf[TRUST_RECORD_LEN], *p;
|
||||
int rc = 0;
|
||||
int i, n;
|
||||
int i;
|
||||
ulong recnum = rec->recnum;
|
||||
|
||||
if( db_fd == -1 )
|
||||
open_db();
|
||||
|
||||
tdbio_dump_record( rec, stdout );
|
||||
|
||||
memset(buf, 0, TRUST_RECORD_LEN);
|
||||
p = buf;
|
||||
*p++ = rec->rectype; p++;
|
||||
@ -900,16 +1104,10 @@ tdbio_dump_record( rec, stdout );
|
||||
BUG();
|
||||
}
|
||||
|
||||
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
|
||||
log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
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 = put_record_into_cache( recnum, buf );
|
||||
if( rc )
|
||||
;
|
||||
if( rec->rectype == RECTYPE_KEY )
|
||||
rc = update_keyhashtbl( rec );
|
||||
else if( rec->rectype == RECTYPE_SDIR )
|
||||
rc = update_sdirhashtbl( rec );
|
||||
@ -990,7 +1188,21 @@ tdbio_new_recnum()
|
||||
memset( &rec, 0, sizeof rec );
|
||||
rec.rectype = 0; /* unused record */
|
||||
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 )
|
||||
log_fatal_f(db_name,_("failed to append a record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
|
@ -166,6 +166,7 @@ const char *tdbio_get_dbname(void);
|
||||
void tdbio_dump_record( TRUSTREC *rec, FILE *fp );
|
||||
int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
|
||||
int tdbio_write_record( TRUSTREC *rec );
|
||||
int tdbio_sync(void);
|
||||
int tdbio_delete_record( ulong recnum );
|
||||
ulong tdbio_new_recnum(void);
|
||||
int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec );
|
||||
|
@ -48,7 +48,7 @@ read_line( byte *buf, size_t *r_buflen, IOBUF a )
|
||||
assert(buflen >= 20 );
|
||||
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] = 0;
|
||||
if( c == -1 ) {
|
||||
@ -58,7 +58,7 @@ read_line( byte *buf, size_t *r_buflen, IOBUF a )
|
||||
}
|
||||
else if( c != '\n' ) {
|
||||
IOBUF b = iobuf_temp();
|
||||
while( (c=iobuf_get2(a)) != -1 && c != '\n' ) {
|
||||
while( (c=iobuf_get(a)) != -1 && c != '\n' ) {
|
||||
iobuf_put(b,c);
|
||||
if( c != ' ' && c != '\t' && c != '\r' )
|
||||
break;
|
||||
|
386
g10/trustdb.c
386
g10/trustdb.c
@ -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 *next;
|
||||
@ -171,6 +166,19 @@ delete_record( ulong recno )
|
||||
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 );
|
||||
rc = get_pubkey( pk, keyid );
|
||||
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] );
|
||||
goto leave;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
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] );
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
/* make sure that the pubkey is in the trustdb */
|
||||
@ -443,12 +451,12 @@ verify_own_keys()
|
||||
if( rc ) {
|
||||
log_error(_("key %08lX: can't put it into the trustdb\n"),
|
||||
(ulong)keyid[1] );
|
||||
goto leave;
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
else if( rc ) {
|
||||
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",
|
||||
(ulong)keyid[1], pk->local_id );
|
||||
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]);
|
||||
|
||||
else if( opt.verbose )
|
||||
log_info(_("key %08lX: accepted as secret key.\n"),
|
||||
(ulong)keyid[1]);
|
||||
skip:
|
||||
release_secret_key_parts( sk );
|
||||
release_public_key_parts( pk );
|
||||
}
|
||||
@ -467,7 +478,6 @@ verify_own_keys()
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
leave:
|
||||
enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
|
||||
free_secret_key( sk );
|
||||
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;
|
||||
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].trust = 0;
|
||||
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);
|
||||
*ret_tslist = tslist;
|
||||
}
|
||||
else
|
||||
; /* FIXME: release tslist */
|
||||
else { /* error: release tslist */
|
||||
while( tslist ) {
|
||||
tsl = tslist->next;
|
||||
m_free(tslist);
|
||||
tslist = tsl;
|
||||
}
|
||||
}
|
||||
release_lid_table(lids);
|
||||
return rc;
|
||||
}
|
||||
@ -865,7 +887,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
|
||||
if( dr->r.dir.dirflags & DIRF_REVOKED )
|
||||
tflags |= TRUST_FLAG_REVOKED;
|
||||
|
||||
#if 0
|
||||
#if 0 /* Do we still need this?? */
|
||||
if( !rc && !dr->r.dir.siglist ) {
|
||||
/* We do not have any signatures; check whether it is one of our
|
||||
* secret keys */
|
||||
@ -1153,6 +1175,7 @@ import_ownertrust( const char *fname )
|
||||
log_error_f(fname, _("read error: %s\n"), strerror(errno) );
|
||||
if( !is_stdin )
|
||||
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.
|
||||
* Special hack: A username "REBUILD" inserts all records from the public
|
||||
* key rings into the trustdb.
|
||||
*/
|
||||
void
|
||||
check_trustdb( const char *username )
|
||||
@ -1257,9 +1278,8 @@ check_trustdb( const char *username )
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
int rc;
|
||||
int rebuild = username && !strcmp(username, "REBUILD");
|
||||
|
||||
if( username && !rebuild ) {
|
||||
if( username ) {
|
||||
rc = find_keyblock_byname( &kbpos, username );
|
||||
if( !rc )
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
@ -1315,46 +1335,51 @@ check_trustdb( const char *username )
|
||||
release_kbnode( keyblock ); keyblock = NULL;
|
||||
}
|
||||
}
|
||||
if( rebuild ) {
|
||||
log_info("adding new entries.\n");
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( !rc ) {
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
rc = update_trust_record( keyblock );
|
||||
if( rc == -1 ) { /* not yet in trustdb: insert */
|
||||
PKT_public_key *pk =
|
||||
find_kbnode( keyblock, PKT_PUBLIC_KEY
|
||||
) ->pkt->pkt.public_key;
|
||||
rc = insert_trust_record( pk );
|
||||
if( rc && !pk->local_id )
|
||||
log_error("lid ?: insert failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
else if( rc )
|
||||
log_error("lid %lu: insert failed: %s\n",
|
||||
pk->local_id, g10_errstr(rc) );
|
||||
else
|
||||
log_info("lid %lu: inserted\n", pk->local_id );
|
||||
}
|
||||
else if( rc )
|
||||
log_error("lid %lu: update failed: %s\n",
|
||||
lid_from_keyblock(keyblock), g10_errstr(rc) );
|
||||
else
|
||||
log_info("lid %lu: updated\n",
|
||||
lid_from_keyblock(keyblock) );
|
||||
}
|
||||
}
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
||||
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
update_trustdb( )
|
||||
{
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
int rc;
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( !rc ) {
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
rc = update_trust_record( keyblock );
|
||||
if( rc == -1 ) { /* not yet in trustdb: insert */
|
||||
PKT_public_key *pk =
|
||||
find_kbnode( keyblock, PKT_PUBLIC_KEY
|
||||
) ->pkt->pkt.public_key;
|
||||
rc = insert_trust_record( pk );
|
||||
if( rc && !pk->local_id )
|
||||
log_error("lid ?: insert failed: %s\n",
|
||||
g10_errstr(rc) );
|
||||
else if( rc )
|
||||
log_error("lid %lu: insert failed: %s\n",
|
||||
pk->local_id, g10_errstr(rc) );
|
||||
else
|
||||
log_info("lid %lu: inserted\n", pk->local_id );
|
||||
}
|
||||
else if( rc )
|
||||
log_error("lid %lu: update failed: %s\n",
|
||||
lid_from_keyblock(keyblock), g10_errstr(rc) );
|
||||
else
|
||||
log_info("lid %lu: updated\n",
|
||||
lid_from_keyblock(keyblock) );
|
||||
}
|
||||
}
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
||||
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Get the trustlevel for this PK.
|
||||
@ -1418,12 +1443,10 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
|
||||
return G10ERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
if( pk->valid_days && add_days_to_timestamp(pk->timestamp,
|
||||
pk->valid_days) < cur_time ) {
|
||||
if( pk->expiredate && pk->expiredate <= cur_time ) {
|
||||
log_info(_("key %08lX.%lu: expired at %s\n"),
|
||||
(ulong)keyid[1], pk->local_id,
|
||||
asctimestamp( add_days_to_timestamp(pk->timestamp,
|
||||
pk->valid_days)));
|
||||
asctimestamp( pk->expiredate) );
|
||||
trustlevel = TRUST_EXPIRED;
|
||||
}
|
||||
else {
|
||||
@ -1485,7 +1508,10 @@ query_trust_info( PKT_public_key *pk )
|
||||
int
|
||||
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 */
|
||||
c = m_alloc_clear( sizeof *c );
|
||||
@ -1652,7 +1678,7 @@ query_trust_record( PKT_public_key *pk )
|
||||
return get_dir_record( pk, &rec );
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Brauchen wir das?? */
|
||||
int
|
||||
clear_trust_checked_flag( PKT_public_key *pk )
|
||||
{
|
||||
@ -1669,6 +1695,7 @@ clear_trust_checked_flag( PKT_public_key *pk )
|
||||
/* reset the flag */
|
||||
rec.r.dir.dirflags &= ~DIRF_CHECKED;
|
||||
write_record( &rec );
|
||||
do_sync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1684,6 +1711,8 @@ check_hint_sig( ulong lid, KBNODE keyblock, u32 *keyid, byte *uidrec_hash,
|
||||
byte uhash[20];
|
||||
int is_selfsig;
|
||||
PKT_signature *sigpkt = NULL;
|
||||
TRUSTREC tmp;
|
||||
u32 sigkid[2];
|
||||
|
||||
if( sigrec->r.sig.sig[sigidx].flag & SIGF_CHECKED )
|
||||
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"),
|
||||
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 */
|
||||
for( node=keyblock; node; node = node->next ) {
|
||||
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 ) {
|
||||
sigpkt = node->pkt->pkt.signature;
|
||||
if( sigpkt->keyid[0] == keyid[0]
|
||||
&& sigpkt->keyid[1] == keyid[1]
|
||||
if( sigpkt->keyid[0] == sigkid[0]
|
||||
&& sigpkt->keyid[1] == sigkid[1]
|
||||
&& (sigpkt->sig_class&~3) == 0x10 )
|
||||
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 );
|
||||
if( is_selfsig ) {
|
||||
log_error(_("lid %lu: self-signature in hintlist\n"), lid );
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
"very strange: no public key for signature %08lX\n"),
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"very strange: no public key\n"),
|
||||
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
||||
(ulong)sigpkt->keyid[1] );
|
||||
sigrec->r.sig.sig[sigidx].flag = SIGF_NOPUBKEY;
|
||||
}
|
||||
else {
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"invalid signature: %s\n"),
|
||||
(ulong)keyid[1], lid,
|
||||
uhash[18], uhash[19], g10_errstr(rc));
|
||||
(ulong)keyid[1], lid, uhash[18], uhash[19],
|
||||
(ulong)sigpkt->keyid[1], g10_errstr(rc) );
|
||||
sigrec->r.sig.sig[sigidx].flag = SIGF_CHECKED;
|
||||
}
|
||||
sigrec->dirty = 1;
|
||||
@ -1930,7 +1981,7 @@ upd_uid_record( PKT_user_id *uid, TRUSTREC *drec, RECNO_LIST *recno_list,
|
||||
|
||||
static void
|
||||
upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
u32 *keyid, ulong *uidrecno, byte *uidhash )
|
||||
u32 *keyid, TRUSTREC *urec, byte *uidhash )
|
||||
{
|
||||
static struct {
|
||||
sigsubpkttype_t subpkttype;
|
||||
@ -1941,7 +1992,7 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
{ SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR },
|
||||
{ 0, 0 }
|
||||
};
|
||||
TRUSTREC urec, prec;
|
||||
TRUSTREC prec;
|
||||
const byte *s;
|
||||
size_t n;
|
||||
int k, i;
|
||||
@ -1949,13 +2000,10 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
int recno_idx = 0;
|
||||
ulong recno;
|
||||
|
||||
/* we need the uid record */
|
||||
read_record( *uidrecno, &urec, RECTYPE_UID );
|
||||
|
||||
/* First delete all pref records
|
||||
* This is much simpler than checking whether we have to
|
||||
* 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 );
|
||||
delete_record( recno );
|
||||
}
|
||||
@ -1999,8 +2047,8 @@ upd_pref_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
write_record( &prec );
|
||||
}
|
||||
/* don't need to write the last one, but update the uid */
|
||||
urec.r.uid.prefrec = recno_idx? recno_tbl[0] : 0;
|
||||
write_record( &urec );
|
||||
urec->r.uid.prefrec = recno_idx? recno_tbl[0] : 0;
|
||||
urec->dirty = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -2014,25 +2062,41 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
u32 *keyid, ulong *uidrecno, byte *uidhash,
|
||||
KBNODE keyblock, KBNODE signode )
|
||||
{
|
||||
TRUSTREC urec;
|
||||
int rc;
|
||||
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( (sig->sig_class&~3) == 0x10 ) {
|
||||
/* must verify this selfsignature here, so that we can
|
||||
* build the preference record and validate the uid record
|
||||
*/
|
||||
if( !*uidrecno ) {
|
||||
log_error("key %08lX: self-signature without user id\n",
|
||||
(ulong)keyid[1] );
|
||||
}
|
||||
else if( (rc = check_key_signature( keyblock, signode, NULL ))) {
|
||||
log_error("key %08lX, uid %02X%02X: "
|
||||
"invalid self-signature: %s\n", (ulong)keyid[1],
|
||||
uidhash[18], uidhash[19], g10_errstr(rc) );
|
||||
}
|
||||
else { /* valid sig (may be revoked, but that doesn't matter here) */
|
||||
upd_pref_record( sig, drec, keyid, uidrecno, uidhash );
|
||||
if( !(urec.r.uid.uidflags & UIDF_CHECKED) ) {
|
||||
rc = check_key_signature( keyblock, signode, NULL );
|
||||
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 {
|
||||
log_error("key %08lX, uid %02X%02X: "
|
||||
"invalid self-signature: %s\n", (ulong)keyid[1],
|
||||
uidhash[18], uidhash[19], g10_errstr(rc) );
|
||||
urec.r.uid.uidflags = UIDF_CHECKED;
|
||||
}
|
||||
urec.dirty = 1;
|
||||
}
|
||||
}
|
||||
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
|
||||
* inserted into the trustdb.
|
||||
*/
|
||||
TRUSTREC urec, rec;
|
||||
TRUSTREC rec;
|
||||
ulong recno;
|
||||
TRUSTREC delrec;
|
||||
int delrecidx;
|
||||
int newflag = 0;
|
||||
ulong newlid = 0;
|
||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||
ulong pk_lid = 0;
|
||||
int found_sig = 0;
|
||||
int found_delrec = 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 ) {
|
||||
int i;
|
||||
|
||||
@ -2070,12 +2159,25 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
for(i=0; i < SIGS_PER_RECORD; i++ ) {
|
||||
TRUSTREC tmp;
|
||||
if( !rec.r.sig.sig[i].lid ) {
|
||||
if( !delrec.recnum ) {
|
||||
if( !found_delrec && !delrec.recnum ) {
|
||||
delrec = rec;
|
||||
delrecidx = i;
|
||||
found_delrec=1;
|
||||
}
|
||||
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 )
|
||||
continue; /* we already checked this signature */
|
||||
if( rec.r.sig.sig[i].flag & SIGF_NOPUBKEY )
|
||||
@ -2087,24 +2189,30 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
* the signature: */
|
||||
rc = check_key_signature( keyblock, signode, NULL );
|
||||
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;
|
||||
}
|
||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
"weird: no public key for signature %08lX\n"),
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"weird: no public key\n"),
|
||||
(ulong)keyid[1], lid, uidhash[18],
|
||||
uidhash[19], (ulong)sig->keyid[1] );
|
||||
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
||||
}
|
||||
else {
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"invalid signature: %s\n"),
|
||||
(ulong)keyid[1], lid,
|
||||
uidhash[18], uidhash[19], g10_errstr(rc));
|
||||
(ulong)keyid[1], lid, uidhash[18],
|
||||
uidhash[19], (ulong)sig->keyid[1],
|
||||
g10_errstr(rc));
|
||||
rec.r.sig.sig[i].flag = SIGF_CHECKED;
|
||||
}
|
||||
write_record( &rec );
|
||||
goto ready;
|
||||
rec.dirty = 1;
|
||||
}
|
||||
else if( tmp.rectype == RECTYPE_SDIR ) {
|
||||
/* must check that it is the right one */
|
||||
@ -2117,11 +2225,10 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
(ulong)keyid[1], lid,
|
||||
uidhash[18], uidhash[19], tmp.recnum );
|
||||
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
|
||||
write_record( &rec );
|
||||
rec.dirty = 1;
|
||||
/* fixme: should we verify that the record is
|
||||
* in the hintlist? - This case here should anyway
|
||||
* never occur */
|
||||
goto ready;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -2130,48 +2237,52 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
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
|
||||
* our list of signatures. Add a new record with that signature
|
||||
* and if the public key is there, check the signature. */
|
||||
rc = get_pubkey( pk, sig->keyid );
|
||||
if( !rc ) {
|
||||
/* 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;
|
||||
else
|
||||
rc = check_key_signature( keyblock, signode, NULL );
|
||||
}
|
||||
|
||||
if( !pk_lid )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else
|
||||
rc = check_key_signature( keyblock, signode, NULL );
|
||||
|
||||
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 )
|
||||
BUG();
|
||||
newflag = SIGF_CHECKED | SIGF_VALID;
|
||||
}
|
||||
else if( rc == G10ERR_NO_PUBKEY ) {
|
||||
if( opt.verbose )
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
"no public key for signature %08lX\n"),
|
||||
if( opt.verbose > 1 )
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"no public key\n"),
|
||||
(ulong)keyid[1], lid, uidhash[18],
|
||||
uidhash[19], (ulong)sig->keyid[1] );
|
||||
newflag = SIGF_NOPUBKEY;
|
||||
}
|
||||
else {
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X: "
|
||||
log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
|
||||
"invalid signature: %s\n"),
|
||||
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
|
||||
g10_errstr(rc));
|
||||
(ulong)sig->keyid[1], g10_errstr(rc));
|
||||
newflag = SIGF_CHECKED;
|
||||
}
|
||||
free_public_key( pk );
|
||||
|
||||
if( !newlid ) { /* create a shadow dir record */
|
||||
TRUSTREC sdir, hlst, tmphlst;
|
||||
@ -2250,16 +2361,17 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
tmp.r.sig.sig[0].flag= newflag;
|
||||
write_record( &tmp );
|
||||
urec.r.uid.siglist = tmp.recnum;
|
||||
write_record( &urec );
|
||||
urec.dirty = 1;
|
||||
}
|
||||
|
||||
ready:
|
||||
;
|
||||
}
|
||||
else {
|
||||
/* handle other sig classes */
|
||||
}
|
||||
|
||||
leave:
|
||||
if( urec.dirty )
|
||||
write_record( &urec );
|
||||
}
|
||||
|
||||
|
||||
@ -2389,7 +2501,7 @@ update_trust_record( KBNODE keyblock )
|
||||
else if( drec.dirty ) {
|
||||
drec.r.dir.dirflags &= ~DIRF_CHECKED; /* reset flag */
|
||||
write_record( &drec );
|
||||
/* fixme: commit_transaction */
|
||||
do_sync();
|
||||
}
|
||||
rel_recno_list( &recno_list );
|
||||
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) */
|
||||
{ PKT_public_key *a_pk;
|
||||
u32 akid[2], bkid[2];
|
||||
|
||||
node = find_kbnode( keyblock, 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");
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
@ -2492,6 +2612,7 @@ insert_trust_record( PKT_public_key *pk )
|
||||
if( rc && hintlist )
|
||||
; /* fixme: the hintlist is not anymore anchored */
|
||||
release_kbnode( keyblock );
|
||||
do_sync();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2504,6 +2625,7 @@ update_ownertrust( ulong lid, unsigned new_trust )
|
||||
read_record( lid, &rec, RECTYPE_DIR );
|
||||
rec.r.dir.ownertrust = new_trust;
|
||||
write_record( &rec );
|
||||
do_sync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ void list_trust_path( int max_depth, const char *username );
|
||||
void export_ownertrust(void);
|
||||
void import_ownertrust(const char *fname);
|
||||
void check_trustdb( const char *username );
|
||||
void update_trustdb( void );
|
||||
int init_trustdb( int level, const char *dbname );
|
||||
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel );
|
||||
int query_trust_info( PKT_public_key *pk );
|
||||
|
@ -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))
|
||||
|
||||
* util.h (HAVE_ATEXIT): New.
|
||||
|
@ -97,7 +97,7 @@ int g10c_debug_mode;
|
||||
int g10_opt_verbose;
|
||||
|
||||
/*-- dynload.c --*/
|
||||
void register_cipher_extension( const char *fname );
|
||||
void register_cipher_extension( const char *mainpgm, const char *fname );
|
||||
|
||||
/*-- md.c --*/
|
||||
int string_to_digest_algo( const char *string );
|
||||
|
@ -41,6 +41,8 @@ struct iobuf_struct {
|
||||
unsigned long nlimit;
|
||||
unsigned long nbytes; /* used together with nlimit */
|
||||
unsigned long ntotal; /* total bytes read (position of stream) */
|
||||
int nofast; /* used by the iobuf_get() */
|
||||
void *directfp;
|
||||
struct {
|
||||
size_t size; /* allocated size */
|
||||
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_temp(void);
|
||||
IOBUF iobuf_open( const char *fname );
|
||||
IOBUF iobuf_fopen( const char *fname, const char *mode );
|
||||
IOBUF iobuf_create( const char *fname );
|
||||
IOBUF iobuf_append( 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.
|
||||
*/
|
||||
#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++] ) )
|
||||
#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
|
||||
* This macro does only write the low order byte
|
||||
*/
|
||||
|
@ -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)
|
||||
|
||||
* mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
|
||||
|
@ -10,6 +10,16 @@ test -d ./mpi || mkdir ./mpi
|
||||
echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
|
||||
|
||||
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*)
|
||||
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
|
||||
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
|
||||
@ -122,7 +132,7 @@ case "${target}" in
|
||||
*-*-linuxaout* | *-*-linuxoldld* | *-*-linux-gnuoldld*)
|
||||
needs_underscore="y"
|
||||
;;
|
||||
*-*-linux* | *-sysv* | *-solaris* | *-gnu*)
|
||||
*-*-linux* | *-sysv* | *-solaris* | *-gnu* | *-freebsd*-elf)
|
||||
needs_underscore="n"
|
||||
;;
|
||||
*)
|
||||
|
5
scripts/ChangeLog
Normal file
5
scripts/ChangeLog
Normal 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
|
||||
|
90
scripts/config.guess
vendored
90
scripts/config.guess
vendored
@ -9,7 +9,7 @@
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
@ -169,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
int main (argc, argv) int argc; char **argv; {
|
||||
#if defined (host_mips) && defined (MIPSEB)
|
||||
#if defined (SYSTYPE_SYSV)
|
||||
@ -204,19 +204,19 @@ EOF
|
||||
echo m88k-motorola-sysv3
|
||||
exit 0 ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
|
||||
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
|
||||
echo m88k-dg-dgux${UNAME_RELEASE}
|
||||
else
|
||||
echo m88k-dg-dguxbcs${UNAME_RELEASE}
|
||||
fi
|
||||
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit 0 ;;
|
||||
M88*:*:R3*:*)
|
||||
@ -234,13 +234,13 @@ EOF
|
||||
exit 0 ;;
|
||||
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
|
||||
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
|
||||
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
|
||||
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
|
||||
i?86:AIX:*:*)
|
||||
echo i386-ibm-aix
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
main()
|
||||
@ -279,9 +279,9 @@ EOF
|
||||
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
|
||||
echo romp-ibm-bsd4.4
|
||||
exit 0 ;;
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
|
||||
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||
*:BOSX:*:*)
|
||||
echo rs6000-bull-bosx
|
||||
exit 0 ;;
|
||||
@ -296,16 +296,16 @@ EOF
|
||||
exit 0 ;;
|
||||
9000/[3478]??:HP-UX:*:*)
|
||||
case "${UNAME_MACHINE}" in
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
|
||||
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||
esac
|
||||
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
@ -313,7 +313,7 @@ EOF
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
|
||||
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
|
||||
results, however. */
|
||||
results, however. */
|
||||
if (CPU_IS_PA_RISC (cpu))
|
||||
{
|
||||
switch (cpu)
|
||||
@ -358,25 +358,25 @@ EOF
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
CRAY*X-MP:*:*:*)
|
||||
echo xmp-cray-unicos
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@ -390,12 +390,12 @@ EOF
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
F300:UNIX_System_V:*:*)
|
||||
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
F301:UNIX_System_V:*:*)
|
||||
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
|
||||
exit 0 ;;
|
||||
@ -409,7 +409,17 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*: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 ;;
|
||||
*:NetBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
@ -542,8 +552,8 @@ EOF
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& echo i486-ncr-sysv4 && exit 0 ;;
|
||||
m68*:LynxOS:2.*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@ -574,9 +584,9 @@ EOF
|
||||
fi
|
||||
exit 0 ;;
|
||||
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
@ -591,11 +601,11 @@ EOF
|
||||
exit 0 ;;
|
||||
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
@ -617,11 +627,11 @@ main ()
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
2
scripts/config.sub
vendored
2
scripts/config.sub
vendored
@ -68,7 +68,7 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
linux-gnu*)
|
||||
linux-gnu*|freebsd*-*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
|
@ -5,3 +5,4 @@ mkinstalldirs
|
||||
mkdiff
|
||||
missing
|
||||
gnupg.spec
|
||||
ChangeLog
|
||||
|
@ -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)
|
||||
|
||||
* memory.c (m_print_stats): New.
|
||||
|
125
util/iobuf.c
125
util/iobuf.c
@ -431,6 +431,13 @@ iobuf_close( IOBUF a )
|
||||
size_t dummy_len;
|
||||
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 ) {
|
||||
a2 = a->chain;
|
||||
if( a->usage == 2 && (rc=iobuf_flush(a)) )
|
||||
@ -602,6 +609,39 @@ iobuf_openrw( const char *fname )
|
||||
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.
|
||||
*/
|
||||
@ -614,6 +654,9 @@ iobuf_push_filter( IOBUF a,
|
||||
size_t dummy_len=0;
|
||||
int rc=0;
|
||||
|
||||
if( a->directfp )
|
||||
BUG();
|
||||
|
||||
if( a->usage == 2 && (rc=iobuf_flush(a)) )
|
||||
return rc;
|
||||
/* make a copy of the current stream, so that
|
||||
@ -640,6 +683,7 @@ iobuf_push_filter( IOBUF a,
|
||||
/* disable nlimit for the new stream */
|
||||
a->ntotal = b->ntotal + b->nbytes;
|
||||
a->nlimit = a->nbytes = 0;
|
||||
a->nofast &= ~1;
|
||||
/* make a link from the new stream to the original stream */
|
||||
a->chain = b;
|
||||
a->opaque = b->opaque;
|
||||
@ -675,6 +719,9 @@ iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
|
||||
size_t dummy_len=0;
|
||||
int rc=0;
|
||||
|
||||
if( a->directfp )
|
||||
BUG();
|
||||
|
||||
if( DBG_IOBUF )
|
||||
log_debug("iobuf-%d.%d: pop '%s'\n", a->no, a->subno, a->desc );
|
||||
if( !a->filter ) { /* this is simple */
|
||||
@ -744,6 +791,7 @@ underflow(IOBUF a)
|
||||
assert( a->d.start == a->d.len );
|
||||
if( a->usage == 3 )
|
||||
return -1; /* EOF because a temp buffer can't do an underflow */
|
||||
|
||||
if( a->filter_eof ) {
|
||||
if( DBG_IOBUF )
|
||||
log_debug("iobuf-%d.%d: filter eof\n", a->no, a->subno );
|
||||
@ -755,6 +803,22 @@ underflow(IOBUF a)
|
||||
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 ) {
|
||||
len = a->d.size;
|
||||
rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
|
||||
@ -790,6 +854,9 @@ underflow(IOBUF a)
|
||||
void
|
||||
iobuf_clear_eof(IOBUF a)
|
||||
{
|
||||
if( a->directfp )
|
||||
return;
|
||||
|
||||
assert(a->usage == 1);
|
||||
|
||||
if( a->filter )
|
||||
@ -806,6 +873,9 @@ iobuf_flush(IOBUF a)
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
if( a->directfp )
|
||||
return 0;
|
||||
|
||||
/*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
|
||||
if( a->usage == 3 )
|
||||
log_bug("temp buffer too short\n");
|
||||
@ -842,6 +912,7 @@ iobuf_readbyte(IOBUF a)
|
||||
return a->unget.buf[a->unget.start++];
|
||||
m_free(a->unget.buf);
|
||||
a->unget.buf = NULL;
|
||||
a->nofast &= ~2;
|
||||
}
|
||||
|
||||
if( a->nlimit && a->nbytes >= a->nlimit )
|
||||
@ -924,6 +995,10 @@ iobuf_peek(IOBUF a, byte *buf, unsigned buflen )
|
||||
int
|
||||
iobuf_writebyte(IOBUF a, unsigned c)
|
||||
{
|
||||
|
||||
if( a->directfp )
|
||||
BUG();
|
||||
|
||||
if( a->d.len == a->d.size )
|
||||
if( iobuf_flush(a) )
|
||||
return -1;
|
||||
@ -937,6 +1012,10 @@ iobuf_writebyte(IOBUF a, unsigned c)
|
||||
int
|
||||
iobuf_write(IOBUF a, byte *buf, unsigned buflen )
|
||||
{
|
||||
|
||||
if( a->directfp )
|
||||
BUG();
|
||||
|
||||
do {
|
||||
for( ; buflen && a->d.len < a->d.size; buflen--, 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 */
|
||||
m_free(a->unget.buf);
|
||||
a->unget.buf = NULL;
|
||||
a->nofast &= ~2;
|
||||
}
|
||||
a->unget.size = temp->d.len;
|
||||
a->unget.buf = m_alloc( a->unget.size );
|
||||
a->nofast |= 2;
|
||||
a->unget.len = temp->d.len;
|
||||
memcpy( a->unget.buf, temp->d.buf, a->unget.len );
|
||||
iobuf_close(temp);
|
||||
@ -1012,6 +1093,10 @@ iobuf_unget_and_close_temp( IOBUF a, IOBUF temp )
|
||||
void
|
||||
iobuf_set_limit( IOBUF a, unsigned long nlimit )
|
||||
{
|
||||
if( nlimit )
|
||||
a->nofast |= 1;
|
||||
else
|
||||
a->nofast &= ~1;
|
||||
a->nlimit = nlimit;
|
||||
a->ntotal += a->nbytes;
|
||||
a->nbytes = 0;
|
||||
@ -1027,6 +1112,15 @@ iobuf_get_filelength( IOBUF a )
|
||||
{
|
||||
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 )
|
||||
if( !a->chain && a->filter == file_filter ) {
|
||||
file_filter_ctx_t *b = a->filter_ov;
|
||||
@ -1061,30 +1155,39 @@ iobuf_seek( IOBUF a, ulong newpos )
|
||||
{
|
||||
file_filter_ctx_t *b = NULL;
|
||||
|
||||
for( ; a; a = a->chain ) {
|
||||
if( !a->chain && a->filter == file_filter ) {
|
||||
b = a->filter_ov;
|
||||
break;
|
||||
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);
|
||||
}
|
||||
if( !a )
|
||||
return -1;
|
||||
|
||||
if( fseek( b->fp, newpos, SEEK_SET ) ) {
|
||||
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
|
||||
return -1;
|
||||
else {
|
||||
for( ; a; a = a->chain ) {
|
||||
if( !a->chain && a->filter == file_filter ) {
|
||||
b = a->filter_ov;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !a )
|
||||
return -1;
|
||||
if( fseek( b->fp, newpos, SEEK_SET ) ) {
|
||||
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
a->d.len = 0; /* discard buffer */
|
||||
a->d.start = 0;
|
||||
a->nbytes = 0;
|
||||
a->nlimit = 0;
|
||||
a->nofast &= ~1;
|
||||
a->ntotal = newpos;
|
||||
a->error = 0;
|
||||
/* remove filters, but the last */
|
||||
while( a->chain )
|
||||
iobuf_pop_filter( a, a->filter, NULL );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user