last local commit

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

View File

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

19
NEWS
View File

@ -2,6 +2,25 @@ Noteworthy changes in version 0.4.2
-----------------------------------
* Fixed this huge memory leak.
* 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
View File

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

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

@ -1,30 +1,41 @@
* change ringedit:
- avoid all copy operations
- delete for update by changing the packet type to a
special unused packet. (export most know about this)
- do an append instead of an update or insert
- export may be used to compress a keyring.
- keep track of all offset in the trustbd and index them
by keyid.
- If the lookup does not find a public key block at the
stored offset disable this keyid.
- If the keyid was not found or is disabled, walk thru
the pubring.
- use ftruncate to recover from keyring errors.
maybe a new option to do this or simply mark the
wrong part as unused.
This makes signature checks and imports much faster; only keys
given by a userid or a fingerprint (RSA only) have to walk tru
the ring.
* There is a new memory leak in update-trustdb
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
OpenBSD binaries are a.out, so every symbol begins with "_"
* use dld if we don't have dlopen.
* should we flush the getkey.c caches while doing an import?
* prefer a type 16 subkey for encryption because pgp cannot handle
type 20.
* calculation of marginals never yields a completely trusted key.
* 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.

View File

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

View File

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

View File

@ -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]*/ /' `

View File

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

View File

@ -89,10 +89,10 @@ fast_random_poll()
}
#ifdef HAVE_DEV_RANDOM /* we have the /dev/random device */
#ifdef HAVE_DEV_RANDOM /* we have the /dev/random devices */
/****************
* Used to open the Linux /dev/random device
* Used to open the Linux and xBSD /dev/random devices
*/
static int
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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
/* g10.c - The GNUPG utility (main for gpg)
/* g10.c - The GnuPG utility (main for gpg)
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* 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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -71,11 +71,6 @@ struct trust_seg_list {
};
typedef struct {
TRUST_SEG_LIST tsl;
int index;
} ENUM_TRUST_WEB_CONTEXT;
struct recno_list_struct {
struct recno_list_struct *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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,6 +10,16 @@ test -d ./mpi || mkdir ./mpi
echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
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
View File

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

90
scripts/config.guess vendored
View File

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

@ -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/'`
;;

View File

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

View File

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

View File

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