mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Epxerimenta support for GDBM keyings.
This commit is contained in:
parent
6e16296864
commit
e309a875cb
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
Wed Oct 21 17:24:24 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* configure.in: Removed gettext kludge
|
||||
* acinclude.m4: Add patched AM_WITH_NKS macro
|
||||
|
||||
Tue Oct 20 19:03:36 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* configure.in: Kludge to make AM_GNU_GETTEXT work,
|
||||
changed some macors to more modern versions. Also
|
||||
changeg the all makefiles to remove duplicate ../intl.
|
||||
* acinclude.m4: Removed the gettext stuff, as this
|
||||
already comes with automake now.
|
||||
|
||||
Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* configure.in (NAME_OF_DEV_RANDOM): New.
|
||||
|
15
NEWS
15
NEWS
@ -1,3 +1,18 @@
|
||||
|
||||
* Fixed the gettext configure bug.
|
||||
|
||||
* Kludge for RSA keys: keyid and length of a RSA key are
|
||||
correctly reported, but you get an error if you try to use
|
||||
this key (If you do not have the non-US version).
|
||||
|
||||
* Experimental support for keyrings stored in a GDBM database.
|
||||
This is *much* faster than a standard keyring. You will notice
|
||||
that the import gets slower with time; the reason is that all
|
||||
new keys are used to verify signatures of previous inserted
|
||||
keys. Use "--keyring gnupg-gdbm:<name-of-gdbm-file>". This is
|
||||
not (yet) supported for secret keys.
|
||||
|
||||
|
||||
Noteworthy changes in version 0.4.2
|
||||
-----------------------------------
|
||||
|
||||
|
8
PROJECTS
8
PROJECTS
@ -1,6 +1,10 @@
|
||||
|
||||
- abstraction of the MPI
|
||||
* abstraction of the MPI
|
||||
|
||||
- Add a way to override the current cipher/md implementations
|
||||
* Add a way to override the current cipher/md implementations
|
||||
by others (using extensions)
|
||||
|
||||
* add a fast-import command which does not do the signature checks
|
||||
of other keys (processing of the sdir hintlist). The signatures
|
||||
may then be verified by a maintainence pass.
|
||||
|
||||
|
2
THANKS
2
THANKS
@ -17,6 +17,8 @@ Ed Boraas ecxjo@esperanto.org
|
||||
Ernst Molitor ernst.molitor@uni-bonn.de
|
||||
Frank Heckenbach heckenb@mi.uni-erlangen.de
|
||||
Gaël Quéri gqueri@mail.dotcom.fr
|
||||
Greg Louis glouis@dynamicro.on.ca
|
||||
Gregory Steuck steuck@iname.com
|
||||
Hendrik Buschkamp buschkamp@rheumanet.org
|
||||
Holger Schurig holger@d.om.org
|
||||
Hugh Daniel hugh@toad.com
|
||||
|
2
TODO
2
TODO
@ -1,6 +1,4 @@
|
||||
|
||||
* There is a new memory leak in update-trustdb :-(
|
||||
|
||||
* Fix ;) revocation and expire stuff.
|
||||
|
||||
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
|
||||
|
85
acinclude.m4
85
acinclude.m4
@ -209,83 +209,12 @@ define(WK_CHECK_MLOCK,
|
||||
])
|
||||
|
||||
|
||||
######################################################################
|
||||
# progtest.m4 from gettext 0.35
|
||||
######################################################################
|
||||
# Search path for a program which passes the given test.
|
||||
# Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
#
|
||||
# This file can be copied and used freely without restrictions. It can
|
||||
# be used in projects which are not available under the GNU Public License
|
||||
# but which still want to provide support for the GNU gettext functionality.
|
||||
# Please note that the actual code is *not* freely available.
|
||||
|
||||
# serial 1
|
||||
|
||||
dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
|
||||
dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
|
||||
AC_DEFUN(AM_PATH_PROG_WITH_TEST,
|
||||
[# Extract the first word of "$2", so it can be a program name with args.
|
||||
set dummy $2; ac_word=[$]2
|
||||
AC_MSG_CHECKING([for $ac_word])
|
||||
AC_CACHE_VAL(ac_cv_path_$1,
|
||||
[case "[$]$1" in
|
||||
/*)
|
||||
ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in ifelse([$5], , $PATH, [$5]); do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
if [$3]; then
|
||||
ac_cv_path_$1="$ac_dir/$ac_word"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
dnl If no 4th arg is given, leave the cache variable unset,
|
||||
dnl so AC_PATH_PROGS will keep looking.
|
||||
ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
|
||||
])dnl
|
||||
;;
|
||||
esac])dnl
|
||||
$1="$ac_cv_path_$1"
|
||||
if test -n "[$]$1"; then
|
||||
AC_MSG_RESULT([$]$1)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AC_SUBST($1)dnl
|
||||
])
|
||||
|
||||
######################################################################
|
||||
# lcmessage.m4 from gettext 0.35
|
||||
######################################################################
|
||||
# Check whether LC_MESSAGES is available in <locale.h>.
|
||||
# Ulrich Drepper <drepper@cygnus.com>, 1995.
|
||||
#
|
||||
# This file can be copied and used freely without restrictions. It can
|
||||
# be used in projects which are not available under the GNU Public License
|
||||
# but which still want to provide support for the GNU gettext functionality.
|
||||
# Please note that the actual code is *not* freely available.
|
||||
|
||||
# serial 1
|
||||
|
||||
AC_DEFUN(AM_LC_MESSAGES,
|
||||
[if test $ac_cv_header_locale_h = yes; then
|
||||
AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
|
||||
[AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
|
||||
am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
|
||||
if test $am_cv_val_LC_MESSAGES = yes; then
|
||||
AC_DEFINE(HAVE_LC_MESSAGES)
|
||||
fi
|
||||
fi])
|
||||
|
||||
######################################################################
|
||||
# gettext.m4 from gettext 0.35
|
||||
######################################################################
|
||||
# Macro to add for using GNU gettext.
|
||||
# Ulrich Drepper <drepper@cygnus.com>, 1995.
|
||||
#
|
||||
@ -294,7 +223,7 @@ AC_DEFUN(AM_LC_MESSAGES,
|
||||
# but which still want to provide support for the GNU gettext functionality.
|
||||
# Please note that the actual code is *not* freely available.
|
||||
|
||||
# serial 5
|
||||
# serial 5 + patch (wk 21.10.98)
|
||||
|
||||
AC_DEFUN(AM_WITH_NLS,
|
||||
[AC_MSG_CHECKING([whether NLS is requested])
|
||||
@ -334,14 +263,15 @@ AC_DEFUN(AM_WITH_NLS,
|
||||
|
||||
if test "$gt_cv_func_gettext_libc" != "yes"; then
|
||||
AC_CHECK_LIB(intl, bindtextdomain,
|
||||
[AC_CACHE_CHECK([for gettext in libintl],
|
||||
gt_cv_func_gettext_libintl,
|
||||
[AC_CHECK_LIB(intl, gettext,
|
||||
gt_cv_func_gettext_libintl=yes,
|
||||
gt_cv_func_gettext_libintl=no)],
|
||||
[AC_CHECK_LIB(intl, gettext,
|
||||
gt_cv_func_gettext_libintl=yes,
|
||||
gt_cv_func_gettext_libintl=no)])
|
||||
fi
|
||||
|
||||
if test "$gt_cv_func_gettext_libintl" = "yes" ; then
|
||||
LIBS="-lintl $LIBS"
|
||||
fi
|
||||
|
||||
if test "$gt_cv_func_gettext_libc" = "yes" \
|
||||
|| test "$gt_cv_func_gettext_libintl" = "yes"; then
|
||||
AC_DEFINE(HAVE_GETTEXT)
|
||||
@ -481,6 +411,7 @@ AC_DEFUN(AM_WITH_NLS,
|
||||
AC_SUBST(POSUB)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(AM_GNU_GETTEXT,
|
||||
[AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
|
@ -1,3 +1,7 @@
|
||||
Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
|
||||
|
||||
* pubkey.c: Hack to allow us to give some info about RSA keys back.
|
||||
|
||||
Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* dynload.c: Support for DLD
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
gnupg_extensions = tiger twofish
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
|
||||
noinst_LIBRARIES = libcipher.a
|
||||
if ENABLE_GNUPG_EXTENSIONS
|
||||
|
@ -309,6 +309,8 @@ pubkey_get_npkey( int algo )
|
||||
if( pubkey_table[i].algo == algo )
|
||||
return pubkey_table[i].npkey;
|
||||
} while( load_pubkey_modules() );
|
||||
if( is_RSA(algo) ) /* special hack, so that we are able to */
|
||||
return 2; /* see the RSA keyids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -324,6 +326,8 @@ pubkey_get_nskey( int algo )
|
||||
if( pubkey_table[i].algo == algo )
|
||||
return pubkey_table[i].nskey;
|
||||
} while( load_pubkey_modules() );
|
||||
if( is_RSA(algo) ) /* special hack, so that we are able to */
|
||||
return 6; /* see the RSA keyids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -339,6 +343,8 @@ pubkey_get_nsig( int algo )
|
||||
if( pubkey_table[i].algo == algo )
|
||||
return pubkey_table[i].nsig;
|
||||
} while( load_pubkey_modules() );
|
||||
if( is_RSA(algo) ) /* special hack, so that we are able to */
|
||||
return 1; /* see the RSA keyids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -354,6 +360,8 @@ pubkey_get_nenc( int algo )
|
||||
if( pubkey_table[i].algo == algo )
|
||||
return pubkey_table[i].nenc;
|
||||
} while( load_pubkey_modules() );
|
||||
if( is_RSA(algo) ) /* special hack, so that we are able to */
|
||||
return 1; /* see the RSA keyids */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -370,6 +378,8 @@ pubkey_nbits( int algo, MPI *pkey )
|
||||
if( pubkey_table[i].algo == algo )
|
||||
return (*pubkey_table[i].get_nbits)( algo, pkey );
|
||||
} while( load_pubkey_modules() );
|
||||
if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
|
||||
return mpi_get_nbits( pkey[0] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
26
configure.in
26
configure.in
@ -3,6 +3,9 @@ dnl Configure template for GNUPG
|
||||
dnl
|
||||
dnl (Process this file with autoconf to produce a configure script.)
|
||||
|
||||
dnl Must reset CDPATH so that bash's cd does not print to stdout
|
||||
CDPATH=
|
||||
|
||||
AC_INIT(g10/g10.c)
|
||||
AC_CONFIG_AUX_DIR(scripts)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@ -53,15 +56,12 @@ AC_ARG_WITH(included-zlib,
|
||||
[g10_force_zlib=yes], [g10_force_zlib=no] )
|
||||
AC_MSG_RESULT($g10_force_zlib)
|
||||
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
WK_CHECK_CACHE
|
||||
|
||||
dnl Checks for programs.
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_ARG_PROGRAM
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
AM_SANITY_CHECK
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
|
||||
@ -87,6 +87,12 @@ case "${target}" in
|
||||
ac_cv_have_dev_random=no
|
||||
AC_DEFINE(USE_RAND_W32)
|
||||
;;
|
||||
*-*-hpux*)
|
||||
if test -z "$GCC" ; then
|
||||
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
|
||||
fi
|
||||
AC_DEFINE(USE_RAND_UNIX)
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE(USE_RAND_UNIX)
|
||||
;;
|
||||
@ -124,6 +130,8 @@ AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
AM_GNU_GETTEXT
|
||||
|
||||
AC_CHECK_LIB(gdbm,gdbm_firstkey)
|
||||
|
||||
if test "$try_dynload" = yes ; then
|
||||
@ -261,12 +269,8 @@ fi
|
||||
fi
|
||||
AC_SUBST(ZLIBS)
|
||||
|
||||
|
||||
WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
|
||||
|
||||
WK_DO_LINK_FILES
|
||||
|
||||
AM_GNU_GETTEXT
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
@ -280,7 +284,5 @@ doc/Makefile
|
||||
tools/Makefile
|
||||
zlib/Makefile
|
||||
checks/Makefile
|
||||
],[echo timestamp >stamp-h; \
|
||||
sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
|
||||
])
|
||||
|
||||
|
22
doc/DETAILS
22
doc/DETAILS
@ -349,6 +349,28 @@ There is one enhancement used with the old style packet headers:
|
||||
+ that this is the last packet.
|
||||
|
||||
|
||||
Usage of gdbm files for keyrings
|
||||
================================
|
||||
The key to store the keyblokc is it's fingerpint, other records
|
||||
are used for secondary keys. fingerprints are always 20 bytes
|
||||
where 16 bit fingerprints are appded with zero.
|
||||
The first byte of the key gives some information on the type of the
|
||||
key.
|
||||
1 = key is a 20 bit fingerprint (16 bytes fpr are padded with zeroes)
|
||||
data is the keyblock
|
||||
2 = key is the complete 8 byte keyid
|
||||
data is a list of 20 byte fingerprints
|
||||
3 = key is the short 4 byte keyid
|
||||
data is a list of 20 byte fingerprints
|
||||
4 = key is the email address
|
||||
data is a list of 20 byte fingerprints
|
||||
|
||||
Data is prepended with a type byte:
|
||||
1 = keyblock
|
||||
2 = list of 20 byte padded fingerprints
|
||||
3 = list of list fingerprints (but how to we key them?)
|
||||
|
||||
|
||||
|
||||
|
||||
Other Notes
|
||||
|
@ -1,3 +1,27 @@
|
||||
Wed Oct 21 18:19:36 1998 Michael Roth <mroth@nessie.de>
|
||||
|
||||
* ringedit.c (add_keyblock_resource): Directory is now created.
|
||||
* tdbio.c (tdbio_set_dbname): New info message.
|
||||
|
||||
Wed Oct 21 11:52:04 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* trustdb.c (update_trustdb): released keyblock in loop.
|
||||
|
||||
* keylist.c (list_block): New.
|
||||
(list_all): Changed to use list_block.
|
||||
|
||||
* trustdb.c: Completed support for GDBM
|
||||
|
||||
* sign.c (only_old_style): Changed the way force_v3 is handled
|
||||
(sign_file): Ditto.
|
||||
(clearsign_file): Ditto.
|
||||
|
||||
* keygen.c (has_invalid_email_chars): Splitted into mailbox and
|
||||
host part.
|
||||
|
||||
* keylist.c (list_one): Add a merge_keys_and_selfsig.
|
||||
* mainproc.c (proc_tree): Ditto.
|
||||
|
||||
Sun Oct 18 11:49:03 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* sign.c (only_old_style): Add option force_v3_sigs
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
EXTRA_DIST = OPTIONS pubring.asc
|
||||
OMIT_DEPENDENCIES = zlib.h zconf.h
|
||||
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
|
||||
@ -76,7 +76,7 @@ gpgm_SOURCES = dearmor.c \
|
||||
# $(common_source)
|
||||
|
||||
|
||||
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
|
||||
LDADD = $(needed_libs) @ZLIBS@ @INTLLIBS@
|
||||
|
||||
gpgm_LDADD = g10maint.o $(LDADD)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* delkey.c - delte keys
|
||||
/* delkey.c - delete keys
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
|
400
g10/getkey.c
400
g10/getkey.c
@ -683,6 +683,182 @@ merge_keys_and_selfsig( KBNODE keyblock )
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name,
|
||||
int mode, byte *namehash, int *use_namehash )
|
||||
{
|
||||
KBNODE k, kk;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_USER_ID
|
||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len, name, mode)) {
|
||||
/* we found a matching name, look for the key */
|
||||
for(kk=keyblock; kk; kk = kk->next ) {
|
||||
if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== kk->pkt->pkt.public_key->pubkey_algo)
|
||||
&& ( !pk->pubkey_usage
|
||||
|| !check_pubkey_algo2(
|
||||
kk->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ))
|
||||
)
|
||||
break;
|
||||
}
|
||||
if( kk ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
*use_namehash = 1;
|
||||
return kk;
|
||||
}
|
||||
else if( is_RSA(pk->pubkey_algo) )
|
||||
log_error("RSA key cannot be used in this version\n");
|
||||
else
|
||||
log_error("No key for userid\n");
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_keyid( KBNODE keyblock, PKT_public_key *pk, u32 *keyid, int mode )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
if( DBG_CACHE )
|
||||
log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
|
||||
(ulong)keyid[0], (ulong)keyid[1], pk->pubkey_algo, mode );
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
if( DBG_CACHE )
|
||||
log_debug(" aki=%08lx%08lx algo=%d\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo );
|
||||
|
||||
if( aki[1] == keyid[1]
|
||||
&& ( mode == 10 || aki[0] == keyid[0] )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ){
|
||||
KBNODE kk;
|
||||
/* cache the userid */
|
||||
for(kk=keyblock; kk; kk = kk->next )
|
||||
if( kk->pkt->pkttype == PKT_USER_ID )
|
||||
break;
|
||||
if( kk )
|
||||
cache_user_id( kk->pkt->pkt.user_id, aki );
|
||||
else
|
||||
log_error("No userid for key\n");
|
||||
return k; /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_first( KBNODE keyblock, PKT_public_key *pk )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
{
|
||||
if( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo )
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static KBNODE
|
||||
find_by_fpr( KBNODE keyblock, PKT_public_key *pk, const char *name, int mode )
|
||||
{
|
||||
KBNODE k;
|
||||
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
|
||||
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
|
||||
|
||||
if( DBG_CACHE ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
log_debug(" aki=%08lx%08lx algo=%d mode=%d an=%u\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo, mode, an );
|
||||
}
|
||||
|
||||
if( an == mode
|
||||
&& !memcmp( afp, name, an)
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo) )
|
||||
return k;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
|
||||
int use_namehash, int primary )
|
||||
{
|
||||
assert( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||
if( primary && !pk->pubkey_usage ) {
|
||||
copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, keyblock );
|
||||
}
|
||||
else {
|
||||
if( primary && pk->pubkey_usage
|
||||
&& check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
|
||||
/* if the usage is not correct, try to use a subkey */
|
||||
KBNODE save_k = k;
|
||||
|
||||
for( ; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
&& !check_pubkey_algo2(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
break;
|
||||
}
|
||||
if( !k )
|
||||
k = save_k;
|
||||
else
|
||||
log_info(_("using secondary key %08lX "
|
||||
"instead of primary key %08lX\n"),
|
||||
(ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
|
||||
(ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
|
||||
);
|
||||
}
|
||||
|
||||
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, k );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -709,175 +885,87 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
|
||||
{
|
||||
int rc;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE k;
|
||||
KBPOS kbpos;
|
||||
int oldmode = set_packet_list_mode(0);
|
||||
byte namehash[20];
|
||||
int use_namehash=0;
|
||||
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else if( rc )
|
||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
/* try the quick functions */
|
||||
k = NULL;
|
||||
switch( mode ) {
|
||||
case 10:
|
||||
case 11:
|
||||
rc = locate_keyblock_by_keyid( &kbpos, keyid, mode==10, 0 );
|
||||
if( !rc )
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( !rc )
|
||||
k = find_by_keyid( keyblock, pk, keyid, mode );
|
||||
break;
|
||||
|
||||
case 16:
|
||||
case 20:
|
||||
rc = locate_keyblock_by_fpr( &kbpos, name, mode, 0 );
|
||||
if( !rc )
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( !rc )
|
||||
k = find_by_fpr( keyblock, pk, name, mode );
|
||||
break;
|
||||
|
||||
default: rc = G10ERR_UNSUPPORTED;
|
||||
}
|
||||
if( !rc ) {
|
||||
if( !k ) {
|
||||
log_error("lookup: key has been located but was not found\n");
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
}
|
||||
else
|
||||
finish_lookup( keyblock, pk, k, namehash, 0, primary );
|
||||
}
|
||||
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
KBNODE k, kk;
|
||||
if( mode < 10 ) { /* name lookup */
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_USER_ID
|
||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len, name, mode)) {
|
||||
/* we found a matching name, look for the key */
|
||||
for(kk=keyblock; kk; kk = kk->next ) {
|
||||
if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== kk->pkt->pkt.public_key->pubkey_algo)
|
||||
&& ( !pk->pubkey_usage
|
||||
|| !check_pubkey_algo2(
|
||||
kk->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ))
|
||||
)
|
||||
break;
|
||||
}
|
||||
if( kk ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( kk->pkt->pkt.public_key, aki );
|
||||
cache_user_id( k->pkt->pkt.user_id, aki );
|
||||
rmd160_hash_buffer( namehash,
|
||||
k->pkt->pkt.user_id->name,
|
||||
k->pkt->pkt.user_id->len );
|
||||
use_namehash = 1;
|
||||
k = kk;
|
||||
break;
|
||||
}
|
||||
else
|
||||
log_error("No key for userid\n");
|
||||
/* if this was not possible, loop over all keyblocks
|
||||
* fixme: If one of the resources in the quick functions above
|
||||
* works, but the key was not found, we will not find it
|
||||
* in the other resources */
|
||||
if( rc == G10ERR_UNSUPPORTED ) {
|
||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
||||
if( !rc ) {
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
if( mode < 10 )
|
||||
k = find_by_name( keyblock, pk, name, mode,
|
||||
namehash, &use_namehash);
|
||||
else if( mode == 10 || mode == 11 )
|
||||
k = find_by_keyid( keyblock, pk, keyid, mode );
|
||||
else if( mode == 15 )
|
||||
k = find_first( keyblock, pk );
|
||||
else if( mode == 16 || mode == 20 )
|
||||
k = find_by_fpr( keyblock, pk, name, mode );
|
||||
else
|
||||
BUG();
|
||||
if( k ) {
|
||||
finish_lookup( keyblock, pk, k, namehash,
|
||||
use_namehash, primary );
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* keyid or fingerprint lookup */
|
||||
if( DBG_CACHE && (mode== 10 || mode==11) ) {
|
||||
log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
|
||||
(ulong)keyid[0], (ulong)keyid[1],
|
||||
pk->pubkey_algo, mode );
|
||||
}
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
if( mode == 10 || mode == 11 ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
if( DBG_CACHE ) {
|
||||
log_debug(" aki=%08lx%08lx algo=%d\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo );
|
||||
}
|
||||
if( aki[1] == keyid[1]
|
||||
&& ( mode == 10 || aki[0] == keyid[0] )
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ){
|
||||
/* cache the userid */
|
||||
for(kk=keyblock; kk; kk = kk->next )
|
||||
if( kk->pkt->pkttype == PKT_USER_ID )
|
||||
break;
|
||||
if( kk )
|
||||
cache_user_id( kk->pkt->pkt.user_id, aki );
|
||||
else
|
||||
log_error("No userid for key\n");
|
||||
break; /* found */
|
||||
}
|
||||
}
|
||||
else if( mode == 15 ) { /* get the first key */
|
||||
if( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo )
|
||||
break;
|
||||
}
|
||||
else if( mode == 16 || mode == 20 ) {
|
||||
byte afp[MAX_FINGERPRINT_LEN];
|
||||
size_t an;
|
||||
|
||||
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
|
||||
|
||||
if( DBG_CACHE ) {
|
||||
u32 aki[2];
|
||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
||||
log_debug(" aki=%08lx%08lx algo=%d mode=%d an=%u\n",
|
||||
(ulong)aki[0], (ulong)aki[1],
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
mode, an );
|
||||
}
|
||||
if( an == mode && !memcmp( afp, name, an)
|
||||
&& ( !pk->pubkey_algo
|
||||
|| pk->pubkey_algo
|
||||
== k->pkt->pkt.public_key->pubkey_algo) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
BUG();
|
||||
} /* end compare public keys */
|
||||
}
|
||||
}
|
||||
if( k ) { /* found */
|
||||
assert( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||
if( primary && !pk->pubkey_usage ) {
|
||||
copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, keyblock );
|
||||
}
|
||||
else {
|
||||
if( primary && pk->pubkey_usage
|
||||
&& check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
|
||||
/* if the usage is not correct, try to use a subkey */
|
||||
KBNODE save_k = k;
|
||||
|
||||
for( ; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
||||
&& !check_pubkey_algo2(
|
||||
k->pkt->pkt.public_key->pubkey_algo,
|
||||
pk->pubkey_usage ) )
|
||||
break;
|
||||
}
|
||||
if( !k )
|
||||
k = save_k;
|
||||
else
|
||||
log_info(_("using secondary key %08lX "
|
||||
"instead of primary key %08lX\n"),
|
||||
(ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
|
||||
(ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
|
||||
);
|
||||
}
|
||||
|
||||
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
|
||||
use_namehash? namehash:NULL);
|
||||
merge_one_pk_and_selfsig( keyblock, k );
|
||||
}
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
release_kbnode( keyblock );
|
||||
keyblock = NULL;
|
||||
}
|
||||
break; /* enumeration */
|
||||
}
|
||||
release_kbnode( keyblock );
|
||||
keyblock = NULL;
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
||||
}
|
||||
if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
else if( rc )
|
||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
||||
|
||||
leave:
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
if( !rc ) {
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
keyblock = NULL;
|
||||
}
|
||||
}
|
||||
else if( rc == -1 )
|
||||
rc = G10ERR_NO_PUBKEY;
|
||||
|
||||
|
||||
release_kbnode( keyblock );
|
||||
set_packet_list_mode(oldmode);
|
||||
if( opt.debug & DBG_MEMSTAT_VALUE ) {
|
||||
|
@ -46,6 +46,7 @@ new_kbnode( PACKET *pkt )
|
||||
n->pkt = pkt;
|
||||
n->flag = 0;
|
||||
n->private_flag=0;
|
||||
n->recno = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ struct kbnode_struct {
|
||||
PACKET *pkt;
|
||||
int flag;
|
||||
int private_flag;
|
||||
ulong recno; /* used while updating the trustdb */
|
||||
};
|
||||
|
||||
|
||||
@ -69,6 +70,7 @@ struct keyblock_pos_struct {
|
||||
int secret; /* working on a secret keyring */
|
||||
#ifdef HAVE_LIBGDBM
|
||||
GDBM_FILE dbf;
|
||||
byte keybuf[21];
|
||||
#endif
|
||||
PACKET *pkt; /* ditto */
|
||||
};
|
||||
@ -172,6 +174,10 @@ const char *enum_keyblock_resources( int *sequence, int secret );
|
||||
int add_keyblock_resource( const char *resname, int force, int secret );
|
||||
const char *keyblock_resource_name( KBPOS *kbpos );
|
||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
||||
int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
|
||||
int fprlen, int secret );
|
||||
int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
|
||||
int shortkid, int secret );
|
||||
int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
|
||||
int find_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||
int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
||||
|
10
g10/keygen.c
10
g10/keygen.c
@ -541,10 +541,18 @@ ask_expiredate()
|
||||
static int
|
||||
has_invalid_email_chars( const char *s )
|
||||
{
|
||||
int at_seen=0;
|
||||
|
||||
for( ; *s; s++ ) {
|
||||
if( *s & 0x80 )
|
||||
return 1;
|
||||
if( !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.@", *s ) )
|
||||
if( *s == '@' )
|
||||
at_seen=1;
|
||||
else if( !at_seen
|
||||
&& !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.+", *s ))
|
||||
return 1;
|
||||
else if( at_seen
|
||||
&& !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.", *s ) )
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
103
g10/keylist.c
103
g10/keylist.c
@ -37,6 +37,7 @@
|
||||
|
||||
static void list_all(int);
|
||||
static void list_one(const char *name, int secret);
|
||||
static void list_keyblock( KBNODE keyblock, int secret );
|
||||
static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
|
||||
|
||||
|
||||
@ -70,63 +71,87 @@ secret_key_list( int nnames, char **names )
|
||||
static void
|
||||
list_all( int secret )
|
||||
{
|
||||
int i, seq=0;
|
||||
const char *s;
|
||||
IOBUF a;
|
||||
KBPOS kbpos;
|
||||
KBNODE keyblock = NULL;
|
||||
int rc=0;
|
||||
int lastresno;
|
||||
|
||||
/* FIXME: this assumes a keyring resource is a plain keyring file */
|
||||
while( (s = enum_keyblock_resources( &seq, secret )) ) {
|
||||
if( !(a = iobuf_open(s)) ) {
|
||||
log_error(_("can't open %s: %s\n"), s, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if( seq > 1 )
|
||||
putchar('\n');
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
if( rc != -1 )
|
||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
lastresno = -1;
|
||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
||||
if( lastresno != kbpos.resno ) {
|
||||
const char *s = keyblock_resource_name( &kbpos );
|
||||
int i;
|
||||
|
||||
lastresno = kbpos.resno;
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
}
|
||||
merge_keys_and_selfsig( keyblock );
|
||||
list_keyblock( keyblock, secret );
|
||||
release_kbnode( keyblock ); keyblock = NULL;
|
||||
}
|
||||
|
||||
if( rc && rc != -1 )
|
||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
||||
|
||||
leave:
|
||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
list_one( const char *name, int secret )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
KBPOS kbpos;
|
||||
|
||||
rc = secret? find_secret_keyblock_byname( &kbpos, name )
|
||||
: find_keyblock_byname( &kbpos, name );
|
||||
if( rc ) {
|
||||
log_error("%s: user not found\n", name );
|
||||
return;
|
||||
}
|
||||
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
|
||||
return;
|
||||
}
|
||||
merge_keys_and_selfsig( keyblock );
|
||||
list_keyblock( keyblock, secret );
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
list_keyblock( KBNODE keyblock, int secret )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
KBPOS kbpos;
|
||||
PKT_public_key *pk;
|
||||
PKT_secret_key *sk;
|
||||
u32 keyid[2];
|
||||
int any=0;
|
||||
int trustletter = 0;
|
||||
|
||||
/* search the userid */
|
||||
rc = secret? find_secret_keyblock_byname( &kbpos, name )
|
||||
: find_keyblock_byname( &kbpos, name );
|
||||
if( rc ) {
|
||||
log_error("%s: user not found\n", name );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* read the keyblock */
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
|
||||
if( !node ) {
|
||||
log_error("Oops; key lost!\n");
|
||||
goto leave;
|
||||
return;
|
||||
}
|
||||
|
||||
if( secret ) {
|
||||
@ -336,12 +361,10 @@ list_one( const char *name, int secret )
|
||||
putchar(':');
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
|
||||
{
|
||||
|
@ -886,10 +886,14 @@ proc_tree( CTX c, KBNODE node )
|
||||
c->local_id = 0;
|
||||
c->trustletter = ' ';
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
merge_keys_and_selfsig( node );
|
||||
list_node( c, node );
|
||||
else if( node->pkt->pkttype == PKT_SECRET_KEY )
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
|
||||
merge_keys_and_selfsig( node );
|
||||
list_node( c, node );
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
/* check all signatures */
|
||||
if( !c->have_data ) {
|
||||
|
551
g10/ringedit.c
551
g10/ringedit.c
@ -35,8 +35,6 @@
|
||||
*
|
||||
* - Delete a key block
|
||||
*
|
||||
* FIXME: Keep track of all nodes, so that a change is propagated
|
||||
* to all nodes. (or use shallow copies and ref-counting?)
|
||||
*/
|
||||
|
||||
|
||||
@ -59,10 +57,10 @@
|
||||
#include "mpi.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "host2net.h"
|
||||
#include "options.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#undef HAVE_LIBGDBM /* <--- not ready */
|
||||
|
||||
struct resource_table_struct {
|
||||
int used;
|
||||
@ -88,6 +86,14 @@ static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
|
||||
static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
|
||||
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
static int do_gdbm_store( KBPOS *kbpos, KBNODE root, int update );
|
||||
static int do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos,
|
||||
const byte *fpr, int fprlen );
|
||||
static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );
|
||||
static int do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root );
|
||||
static int do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root );
|
||||
#endif
|
||||
|
||||
|
||||
static RESTBL *
|
||||
@ -100,6 +106,14 @@ check_pos( KBPOS *kbpos )
|
||||
return resource_table + kbpos->resno;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
static void
|
||||
fatal_gdbm_error( const char *string )
|
||||
{
|
||||
log_fatal("gdbm failed: %s\n", string);
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBGDBM */
|
||||
|
||||
/****************************************************************
|
||||
****************** public functions ****************************
|
||||
@ -188,9 +202,33 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* see whether we can determine the filetype */
|
||||
if( rt == rt_UNKNOWN ) {
|
||||
FILE *fp = fopen( filename, "rb" );
|
||||
|
||||
if( fp ) {
|
||||
u32 magic;
|
||||
|
||||
if( fread( &magic, 4, 1, fp) == 1 ) {
|
||||
if( magic == 0x13579ace )
|
||||
rt = rt_GDBM;
|
||||
else if( magic == 0xce9a5713 )
|
||||
log_error("%s: endianess does not match\n", url );
|
||||
else
|
||||
rt = rt_RING;
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
else /* no file yet: create ring */
|
||||
rt = rt_RING;
|
||||
}
|
||||
|
||||
switch( rt ) {
|
||||
case rt_UNKNOWN:
|
||||
log_error("%s: unknown resource type\n", url );
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
|
||||
case rt_RING:
|
||||
iobuf = iobuf_fopen( filename, "rb" );
|
||||
if( !iobuf && !force ) {
|
||||
@ -199,20 +237,46 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
}
|
||||
|
||||
if( !iobuf ) {
|
||||
char *last_slash_in_filename;
|
||||
|
||||
last_slash_in_filename = strrchr(filename, '/');
|
||||
*last_slash_in_filename = 0;
|
||||
|
||||
if( access(filename, F_OK) ) {
|
||||
if( strlen(filename) >= 7
|
||||
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
|
||||
#if __MINGW32__
|
||||
if( mkdir(filename) )
|
||||
#else
|
||||
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
|
||||
#endif
|
||||
{
|
||||
log_error( _("%s: can't create directory: %s\n"),
|
||||
filename, strerror(errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
log_info( _("%s: directory created\n"), filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
*last_slash_in_filename = '/';
|
||||
|
||||
iobuf = iobuf_create( filename );
|
||||
if( !iobuf ) {
|
||||
log_error("%s: can't create: %s\n", filename, strerror(errno));
|
||||
log_error("%s: can't create keyring: %s\n", filename, strerror(errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
else
|
||||
log_info("%s: keyring created\n", filename );
|
||||
}
|
||||
/* fixme: see whether it is really a ring or if type is unknown,
|
||||
* try to figure out of what type it is
|
||||
*/
|
||||
rt = rt_RING; /* <--- FIXME */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* must close it again */
|
||||
iobuf_close( iobuf );
|
||||
@ -222,6 +286,17 @@ add_keyblock_resource( const char *url, int force, int secret )
|
||||
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
resource_table[i].dbf = gdbm_open( filename, 0,
|
||||
force? GDBM_WRCREAT : GDBM_WRITER,
|
||||
S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IWGRP | S_IROTH,
|
||||
fatal_gdbm_error );
|
||||
if( !resource_table[i].dbf ) {
|
||||
log_error("%s: can't open gdbm file: %s\n",
|
||||
filename, gdbm_strerror(gdbm_errno));
|
||||
rc = G10ERR_OPEN_FILE;
|
||||
goto leave;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -310,14 +385,21 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
|
||||
resource_table[i].fname );
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM
|
||||
rc = do_gdbm_search( pkt, kbpos, resource_table[i].dbf,
|
||||
resource_table[i].fname );
|
||||
case rt_GDBM: {
|
||||
PKT_public_key *req_pk = pkt->pkt.public_key;
|
||||
byte fpr[20];
|
||||
size_t fprlen;
|
||||
|
||||
fingerprint_from_pk( req_pk, fpr, &fprlen );
|
||||
rc = do_gdbm_locate( resource_table[i].dbf,
|
||||
kbpos, fpr, fprlen );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
}
|
||||
|
||||
kbpos->rt = resource_table[i].rt;
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
@ -404,6 +486,92 @@ find_secret_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Locate a keyblock in a database which is capable of direct access
|
||||
* Put all information into KBPOS, which can be later be to access this
|
||||
* key block.
|
||||
* This function looks into all registered keyblock sources.
|
||||
*
|
||||
* Returns: 0 if found,
|
||||
* -1 if not found
|
||||
* G10ERR_UNSUPPORTED if no resource is able to handle this
|
||||
* or another errorcode.
|
||||
*/
|
||||
int
|
||||
locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr, int fprlen, int secret )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate( rentry->dbf, kbpos, fpr, fprlen );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int shortkid, int secret )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
int i, rc, any=0, last_rc=-1;
|
||||
|
||||
if( shortkid )
|
||||
return G10ERR_UNSUPPORTED;
|
||||
|
||||
for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
|
||||
if( rentry->used && !rentry->secret == !secret ) {
|
||||
kbpos->rt = rentry->rt;
|
||||
switch( rentry->rt ) {
|
||||
case rt_GDBM:
|
||||
any = 1;
|
||||
rc = do_gdbm_locate_by_keyid( rentry->dbf, kbpos, keyid );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( !rc ) {
|
||||
kbpos->resno = i;
|
||||
kbpos->fp = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("error searching resource %d: %s\n",
|
||||
i, g10_errstr(rc));
|
||||
last_rc = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Lock the keyblock; wait until it's available
|
||||
@ -502,7 +670,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
/* FIXME: make sure that there is only one enum at a time */
|
||||
kbpos->offset = 0;
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
@ -521,7 +690,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_enum( kbpos, ret_root );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
@ -548,11 +717,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
|
||||
kbpos->fp = NULL;
|
||||
}
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
}
|
||||
/* release pending packet */
|
||||
@ -583,7 +749,7 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_store( kbpos, root, 0 );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
@ -639,7 +805,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
|
||||
break;
|
||||
#ifdef HAVE_LIBGDBM
|
||||
case rt_GDBM:
|
||||
/* FIXME!!!! */
|
||||
rc = do_gdbm_store( kbpos, root, 1 );
|
||||
break;
|
||||
#endif
|
||||
default: BUG();
|
||||
@ -1129,58 +1295,179 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
|
||||
********** Functions which operates on GDM files ***************
|
||||
****************************************************************/
|
||||
|
||||
#if MAX_FINGERPRINT_LEN > 20
|
||||
#error A GDBM keyring assumes that fingerprints are less than 21
|
||||
#endif
|
||||
|
||||
/****************
|
||||
* Insert the keyblock into the GDBM database
|
||||
*/
|
||||
|
||||
static int
|
||||
do_gdbm_store( KBPOS *kbpos, KBNODE root, int update )
|
||||
{
|
||||
RESTBL *rentry;
|
||||
PKT_public_key *pk;
|
||||
KBNODE kbctx, node;
|
||||
IOBUF fp = NULL;
|
||||
byte fpr[20];
|
||||
byte contbuf[21];
|
||||
byte keybuf[21];
|
||||
size_t fprlen;
|
||||
datum key, content;
|
||||
int i, rc;
|
||||
|
||||
if( !(rentry = check_pos( kbpos )) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
/* construct the fingerprint which is used as the primary key */
|
||||
node = find_kbnode( root, PKT_PUBLIC_KEY );
|
||||
if( !node )
|
||||
log_bug("a gdbm database can't store secret keys\n");
|
||||
pk = node->pkt->pkt.public_key;
|
||||
|
||||
fingerprint_from_pk( pk, fpr, &fprlen );
|
||||
for(i=fprlen; i < DIM(fpr); i++ )
|
||||
fpr[i] = 0;
|
||||
|
||||
/* build the keyblock */
|
||||
kbctx=NULL;
|
||||
fp = iobuf_temp();
|
||||
iobuf_put( fp, 1 ); /* data is a keyblock */
|
||||
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
|
||||
if( (rc = build_packet( fp, node->pkt )) ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
/* store data and key */
|
||||
*keybuf = 1; /* key is a padded fingerprint */
|
||||
memcpy(keybuf+1, fpr, 20 );
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 21;
|
||||
content.dptr = iobuf_get_temp_buffer( fp );
|
||||
content.dsize = iobuf_get_temp_length( fp );
|
||||
rc = gdbm_store( rentry->dbf, key, content,
|
||||
update? GDBM_REPLACE : GDBM_INSERT );
|
||||
if( rc ) {
|
||||
log_error("%s: gdbm_store failed: %s\n", rentry->fname,
|
||||
rc == 1 ? "already stored"
|
||||
: gdbm_strerror(gdbm_errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
/* now store all keyids */
|
||||
*contbuf = 2; /* data is a list of fingerprints */
|
||||
memcpy(contbuf+1, fpr, 20 );
|
||||
content.dptr = contbuf;
|
||||
content.dsize= 21;
|
||||
kbctx=NULL;
|
||||
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||
u32 aki[2];
|
||||
|
||||
keyid_from_pk( node->pkt->pkt.public_key, aki );
|
||||
*keybuf = 2; /* key is a 8 byte keyid */
|
||||
u32tobuf( keybuf+1 , aki[0] );
|
||||
u32tobuf( keybuf+5, aki[1] );
|
||||
key.dptr = keybuf;
|
||||
key.dsize= 9;
|
||||
/* fixme: must be more clever when a insert failed:
|
||||
* build a list of fingerprints in this case */
|
||||
rc = gdbm_store( rentry->dbf, key, content,
|
||||
update? GDBM_REPLACE : GDBM_INSERT );
|
||||
if( rc ) {
|
||||
log_info("%s: gdbm_store keyid failed: %s\n", rentry->fname,
|
||||
rc == 1 ? "already stored"
|
||||
: gdbm_strerror(gdbm_errno) );
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
iobuf_close(fp); /* don't need a cancel because it is a temp iobuf */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* search one keybox, return 0 if found, -1 if not found or an errorcode.
|
||||
*/
|
||||
static int
|
||||
do_gdbm_search( PACKET *req, KBPOS *kbpos, GDBM_FILE dbf, const char *fname )
|
||||
do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos, const byte *fpr, int fprlen )
|
||||
{
|
||||
byte *keybuf = kbpos->keybuf;
|
||||
datum key;
|
||||
int i;
|
||||
|
||||
*keybuf = 1;
|
||||
for(i=0; i < fprlen; i++ )
|
||||
keybuf[i+1] = fpr[i];
|
||||
for(; i < 20; i++ )
|
||||
keybuf[i+1] = 0;
|
||||
|
||||
/* fetch the data */
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 21;
|
||||
if( !gdbm_exists( dbf, key ) )
|
||||
return -1; /* not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************
|
||||
* locate by keyid.
|
||||
* FIXME: we must have a way to enumerate thru the list opf fingerprints
|
||||
*/
|
||||
static int
|
||||
do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
|
||||
{
|
||||
byte keybuf[9];
|
||||
datum key, content;
|
||||
int rc;
|
||||
PACKET pkt;
|
||||
int save_mode;
|
||||
ulong offset;
|
||||
int pkttype = req->pkttype;
|
||||
PKT_public_key *req_pk = req->pkt.public_key;
|
||||
PKT_secret_key *req_sk = req->pkt.secret_key;
|
||||
|
||||
init_packet(&pkt);
|
||||
save_mode = set_packet_list_mode(0);
|
||||
/* construct the fingerprint which is used as the primary key */
|
||||
*keybuf = 2;
|
||||
u32tobuf( keybuf+1, keyid[0] );
|
||||
u32tobuf( keybuf+5, keyid[1] );
|
||||
|
||||
/* fetch the data */
|
||||
key.dptr = keybuf;
|
||||
key.dsize = 9;
|
||||
content = gdbm_fetch( dbf, key );
|
||||
if( !content.dptr )
|
||||
return -1;
|
||||
|
||||
while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
|
||||
if( pkt.pkttype == PKT_SECRET_KEY ) {
|
||||
PKT_secret_key *sk = pkt.pkt.secret_key;
|
||||
|
||||
if( req_sk->timestamp == sk->timestamp
|
||||
&& req_sk->pubkey_algo == sk->pubkey_algo
|
||||
&& !cmp_seckey( req_sk, sk) )
|
||||
break; /* found */
|
||||
}
|
||||
else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
|
||||
PKT_public_key *pk = pkt.pkt.public_key;
|
||||
|
||||
if( req_pk->timestamp == pk->timestamp
|
||||
&& req_pk->pubkey_algo == pk->pubkey_algo
|
||||
&& !cmp_pubkey( req_pk, pk ) )
|
||||
break; /* found */
|
||||
}
|
||||
else
|
||||
BUG();
|
||||
free_packet(&pkt);
|
||||
if( content.dsize < 2 ) {
|
||||
log_error("gdbm_fetch did not return enough data\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( !rc )
|
||||
kbpos->offset = offset;
|
||||
if( *content.dptr != 2 ) {
|
||||
log_error("gdbm_fetch returned unexpected type %d\n",
|
||||
*(byte*)content.dptr );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize < 21 ) {
|
||||
log_error("gdbm_fetch did not return a complete fingerprint\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize > 21 )
|
||||
log_info("gdbm_fetch: warning: more than one fingerprint\n" );
|
||||
|
||||
leave:
|
||||
free_packet(&pkt);
|
||||
set_packet_list_mode(save_mode);
|
||||
#if __MINGW32__
|
||||
iobuf_close(iobuf);
|
||||
#endif
|
||||
rc = do_gdbm_locate( dbf, kbpos, content.dptr+1, 20 );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
@ -1189,22 +1476,32 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
RESTBL *rentry;
|
||||
KBNODE root = NULL;
|
||||
IOBUF a;
|
||||
int in_cert = 0;
|
||||
datum key, content;
|
||||
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
a = iobuf_fopen( rentry->fname, "rb" );
|
||||
if( !a ) {
|
||||
log_error("can't open '%s'\n", rentry->fname );
|
||||
return G10ERR_OPEN_FILE;
|
||||
key.dptr = kbpos->keybuf;
|
||||
key.dsize = 21;
|
||||
content = gdbm_fetch( rentry->dbf, key );
|
||||
if( !content.dptr ) {
|
||||
log_error("gdbm_fetch failed: %s\n", gdbm_strerror(gdbm_errno) );
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( content.dsize < 2 ) {
|
||||
log_error("gdbm_fetch did not return enough data\n" );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
if( *content.dptr != 1 ) {
|
||||
log_error("gdbm_fetch returned unexpected type %d\n",
|
||||
*(byte*)content.dptr );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
|
||||
if( iobuf_seek( a, kbpos->offset ) ) {
|
||||
log_error("can't seek to %lu\n", kbpos->offset);
|
||||
iobuf_close(a);
|
||||
return G10ERR_KEYRING_OPEN;
|
||||
}
|
||||
a = iobuf_temp_with_content( content.dptr+1, content.dsize-1 );
|
||||
free( content.dptr ); /* can't use m_free() here */
|
||||
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
@ -1214,7 +1511,7 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
if( rc != G10ERR_UNKNOWN_PACKET ) {
|
||||
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
goto ready;
|
||||
break;
|
||||
}
|
||||
kbpos->count++;
|
||||
free_packet( pkt );
|
||||
@ -1222,27 +1519,16 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
continue;
|
||||
}
|
||||
/* make a linked list of all packets */
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_KEY:
|
||||
case PKT_SECRET_KEY:
|
||||
if( in_cert )
|
||||
goto ready;
|
||||
in_cert = 1;
|
||||
default:
|
||||
kbpos->count++;
|
||||
if( !root )
|
||||
root = new_kbnode( pkt );
|
||||
else
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
kbpos->count++;
|
||||
if( !root )
|
||||
root = new_kbnode( pkt );
|
||||
else
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
}
|
||||
ready:
|
||||
if( rc == -1 && root )
|
||||
rc = 0;
|
||||
|
||||
if( rc )
|
||||
release_kbnode( root );
|
||||
else
|
||||
@ -1254,84 +1540,43 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Enum over keyblok data
|
||||
*/
|
||||
static int
|
||||
do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
|
||||
do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
PACKET *pkt;
|
||||
int rc;
|
||||
RESTBL *rentry;
|
||||
KBNODE root = NULL;
|
||||
datum key, helpkey;
|
||||
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
if( kbpos->pkt ) {
|
||||
root = new_kbnode( kbpos->pkt );
|
||||
kbpos->pkt = NULL;
|
||||
if( !kbpos->offset ) {
|
||||
kbpos->offset = 1;
|
||||
key = gdbm_firstkey( rentry->dbf );
|
||||
}
|
||||
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
|
||||
if( rc ) { /* ignore errors */
|
||||
if( rc != G10ERR_UNKNOWN_PACKET ) {
|
||||
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
|
||||
rc = G10ERR_INV_KEYRING;
|
||||
goto ready;
|
||||
}
|
||||
free_packet( pkt );
|
||||
init_packet( pkt );
|
||||
continue;
|
||||
}
|
||||
/* make a linked list of all packets */
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_KEY:
|
||||
case PKT_SECRET_KEY:
|
||||
if( root ) { /* store this packet */
|
||||
kbpos->pkt = pkt;
|
||||
pkt = NULL;
|
||||
goto ready;
|
||||
}
|
||||
root = new_kbnode( pkt );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* skip pakets at the beginning of a keyring, until we find
|
||||
* a start packet; issue a warning if it is not a comment */
|
||||
if( !root && pkt->pkttype != PKT_COMMENT
|
||||
&& pkt->pkttype != PKT_OLD_COMMENT ) {
|
||||
log_info("keyring_enum: skipped packet of type %d\n",
|
||||
pkt->pkttype );
|
||||
break;
|
||||
}
|
||||
if( !root || (skipsigs && ( pkt->pkttype == PKT_SIGNATURE
|
||||
||pkt->pkttype == PKT_COMMENT
|
||||
||pkt->pkttype == PKT_OLD_COMMENT )) ) {
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
helpkey.dptr = kbpos->keybuf;
|
||||
helpkey.dsize= 21;
|
||||
key = gdbm_nextkey( rentry->dbf, helpkey );
|
||||
}
|
||||
ready:
|
||||
if( rc == -1 && root )
|
||||
rc = 0;
|
||||
while( key.dptr && (!key.dsize || *key.dptr != 1) ) {
|
||||
helpkey = key;
|
||||
key = gdbm_nextkey( rentry->dbf, helpkey );
|
||||
free( helpkey.dptr ); /* free and not m_free() ! */
|
||||
}
|
||||
if( !key.dptr )
|
||||
return -1; /* eof */
|
||||
|
||||
if( rc )
|
||||
release_kbnode( root );
|
||||
else
|
||||
*ret_root = root;
|
||||
free_packet( pkt );
|
||||
m_free( pkt );
|
||||
|
||||
return rc;
|
||||
if( key.dsize < 21 ) {
|
||||
free( key.dptr ); /* free and not m_free() ! */
|
||||
log_error("do_gdm_enum: key is too short\n" );
|
||||
return G10ERR_INV_KEYRING;
|
||||
}
|
||||
memcpy( kbpos->keybuf, key.dptr, 21 );
|
||||
free( key.dptr ); /* free and not m_free() ! */
|
||||
return do_gdbm_read( kbpos, ret_root );
|
||||
}
|
||||
|
||||
#endif /*HAVE_LIBGDBM*/
|
||||
|
||||
|
||||
|
@ -108,9 +108,6 @@ only_old_style( SK_LIST sk_list )
|
||||
SK_LIST sk_rover = NULL;
|
||||
int old_style = 0;
|
||||
|
||||
if( opt.force_v3_sigs )
|
||||
return 1;
|
||||
|
||||
/* if there are only old style capable key we use the old sytle */
|
||||
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
||||
PKT_secret_key *sk = sk_rover->sk;
|
||||
@ -159,7 +156,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
int compr_algo = -1; /* unknown */
|
||||
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
memset( &mfx, 0, sizeof mfx);
|
||||
@ -181,6 +177,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
goto leave;
|
||||
if( !old_style )
|
||||
old_style = only_old_style( sk_list );
|
||||
|
||||
if( encrypt ) {
|
||||
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
|
||||
goto leave;
|
||||
@ -372,7 +369,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
/* build the signature packet */
|
||||
/* fixme: this code is partly duplicated in make_keysig_packet */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = old_style? 3 : sk->version;
|
||||
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
|
||||
keyid_from_sk( sk, sig->keyid );
|
||||
sig->digest_algo = hash_for(sk->pubkey_algo);
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
@ -608,7 +605,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
/* build the signature packet */
|
||||
/* fixme: this code is duplicated above */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = old_style? 3 : sk->version;
|
||||
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
|
||||
keyid_from_sk( sk, sig->keyid );
|
||||
sig->digest_algo = hash_for(sk->pubkey_algo);
|
||||
sig->pubkey_algo = sk->pubkey_algo;
|
||||
|
148
g10/tdbio.c
148
g10/tdbio.c
@ -269,7 +269,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
|
||||
if( access( fname, R_OK ) ) {
|
||||
if( errno != ENOENT ) {
|
||||
log_error_f( fname, _("can't access: %s\n"), strerror(errno) );
|
||||
log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
|
||||
m_free(fname);
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
@ -289,17 +289,19 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
#endif
|
||||
log_fatal_f( fname, _("can't create directory: %s\n"),
|
||||
strerror(errno) );
|
||||
log_fatal( _("%s: can't create directory: %s\n"),
|
||||
fname, strerror(errno) );
|
||||
else
|
||||
log_info( _("%s: directory created\n"), fname );
|
||||
}
|
||||
else
|
||||
log_fatal_f(fname, _("directory does not exist!\n") );
|
||||
log_fatal( _("%s: directory does not exist!\n"), fname );
|
||||
}
|
||||
*p = '/';
|
||||
|
||||
fp =fopen( fname, "wb" );
|
||||
if( !fp )
|
||||
log_fatal_f( fname, _("can't create: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
|
||||
fclose(fp);
|
||||
m_free(db_name);
|
||||
db_name = fname;
|
||||
@ -309,7 +311,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
#endif
|
||||
if( db_fd == -1 )
|
||||
log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
|
||||
memset( &rec, 0, sizeof rec );
|
||||
rec.r.ver.version = 2;
|
||||
@ -320,11 +322,14 @@ tdbio_set_dbname( const char *new_dbname, int create )
|
||||
if( !rc )
|
||||
tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( fname, _("failed to create version record: %s"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: failed to create version record: %s"),
|
||||
fname, g10_errstr(rc));
|
||||
/* and read again to check that we are okay */
|
||||
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
|
||||
log_fatal_f( db_name, "invalid trust-db created\n" );
|
||||
log_fatal( _("%s: invalid trust-db created\n"), db_name );
|
||||
|
||||
log_info(_("%s: trust-db created\n"), db_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -354,9 +359,9 @@ open_db()
|
||||
db_fd = open( db_name, O_RDWR );
|
||||
#endif
|
||||
if( db_fd == -1 )
|
||||
log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
|
||||
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
|
||||
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
|
||||
log_fatal_f( db_name, _("invalid trust-db\n") );
|
||||
log_fatal( _("%s: invalid trust-db\n"), db_name );
|
||||
/* fixme: check ->locked and other stuff */
|
||||
}
|
||||
|
||||
@ -390,16 +395,16 @@ create_hashtable( TRUSTREC *vr, int type )
|
||||
rec.recnum = recnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to create hashtable: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: failed to create hashtable: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
/* update the version record */
|
||||
rc = tdbio_write_record( vr );
|
||||
if( !rc )
|
||||
rc = tdbio_sync();
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error updating version record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal( _("%s: error updating version record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
|
||||
|
||||
@ -418,8 +423,8 @@ get_keyhashrec()
|
||||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( !vr.r.ver.keyhashtbl )
|
||||
create_hashtable( &vr, 0 );
|
||||
|
||||
@ -443,8 +448,8 @@ get_sdirhashrec()
|
||||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( !vr.r.ver.sdirhashtbl )
|
||||
create_hashtable( &vr, 1 );
|
||||
|
||||
@ -744,14 +749,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
rec->r.dir.uidlist,
|
||||
rec->r.dir.cacherec,
|
||||
rec->r.dir.ownertrust );
|
||||
if( rec->r.dir.dirflags & DIRF_ERROR )
|
||||
fputs(", error", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_CHECKED )
|
||||
fputs(", checked", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_MISKEY )
|
||||
fputs(", miskey", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_CHECKED ) {
|
||||
if( rec->r.dir.dirflags & DIRF_VALID )
|
||||
fputs(", valid", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_EXPIRED )
|
||||
fputs(", expired", fp );
|
||||
if( rec->r.dir.dirflags & DIRF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_KEY:
|
||||
@ -761,8 +766,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
rec->r.key.pubkey_algo );
|
||||
for(i=0; i < rec->r.key.fingerprint_len; i++ )
|
||||
fprintf(fp, "%02X", rec->r.key.fingerprint[i] );
|
||||
if( rec->r.key.keyflags & KEYF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
if( rec->r.key.keyflags & KEYF_CHECKED ) {
|
||||
if( rec->r.key.keyflags & KEYF_VALID )
|
||||
fputs(", valid", fp );
|
||||
if( rec->r.key.keyflags & KEYF_EXPIRED )
|
||||
fputs(", expired", fp );
|
||||
if( rec->r.key.keyflags & KEYF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_UID:
|
||||
@ -772,12 +783,12 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
rec->r.uid.prefrec,
|
||||
rec->r.uid.siglist,
|
||||
rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
|
||||
if( rec->r.uid.uidflags & UIDF_CHECKED )
|
||||
fputs(", checked", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_VALID )
|
||||
fputs(", valid", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_CHECKED ) {
|
||||
if( rec->r.uid.uidflags & UIDF_VALID )
|
||||
fputs(", valid", fp );
|
||||
if( rec->r.uid.uidflags & UIDF_REVOKED )
|
||||
fputs(", revoked", fp );
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
case RECTYPE_PREF:
|
||||
@ -795,9 +806,19 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp )
|
||||
fprintf(fp, "sig %lu, next=%lu,",
|
||||
rec->r.sig.lid, rec->r.sig.next );
|
||||
for(i=0; i < SIGS_PER_RECORD; i++ ) {
|
||||
if( rec->r.sig.sig[i].lid )
|
||||
fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].lid,
|
||||
rec->r.sig.sig[i].flag );
|
||||
if( rec->r.sig.sig[i].lid ) {
|
||||
fprintf(fp, " %lu:", rec->r.sig.sig[i].lid );
|
||||
if( rec->r.sig.sig[i].flag & SIGF_CHECKED ) {
|
||||
fprintf(fp,"%c%c%c",
|
||||
(rec->r.sig.sig[i].flag & SIGF_VALID) ? 'V':'-',
|
||||
(rec->r.sig.sig[i].flag & SIGF_EXPIRED) ? 'E':'-',
|
||||
(rec->r.sig.sig[i].flag & SIGF_REVOKED) ? 'R':'-');
|
||||
}
|
||||
else if( rec->r.sig.sig[i].flag & SIGF_NOPUBKEY)
|
||||
fputs("?--", fp);
|
||||
else
|
||||
fputs("---", fp);
|
||||
}
|
||||
}
|
||||
putc('\n', fp);
|
||||
break;
|
||||
@ -876,7 +897,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
break;
|
||||
case RECTYPE_VER: /* version record */
|
||||
if( memcmp(buf+1, "gpg", 3 ) ) {
|
||||
log_error_f( db_name, _("not a trustdb file\n") );
|
||||
log_error( _("%s: not a trustdb file\n"), db_name );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
p += 2; /* skip "pgp" */
|
||||
@ -890,12 +911,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
rec->r.ver.firstfree =buftoulong(p); p += 4;
|
||||
rec->r.ver.sdirhashtbl =buftoulong(p); p += 4;
|
||||
if( recnum ) {
|
||||
log_error_f( db_name, "version record with recnum %lu\n",
|
||||
log_error( _("%s: version record with recnum %lu\n"), db_name,
|
||||
(ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
else if( rec->r.ver.version != 2 ) {
|
||||
log_error_f( db_name, "invalid file version %d\n",
|
||||
log_error( _("%s: invalid file version %d\n"), db_name,
|
||||
rec->r.ver.version );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
@ -911,8 +932,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
rec->r.dir.ownertrust = *p++;
|
||||
rec->r.dir.dirflags = *p++;
|
||||
if( rec->r.dir.lid != recnum ) {
|
||||
log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
|
||||
rec->r.dir.lid, (ulong)recnum );
|
||||
log_error( "%s: dir LID != recnum (%lu,%lu)\n",
|
||||
db_name, rec->r.dir.lid, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
break;
|
||||
@ -957,8 +978,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
p += 3;
|
||||
rec->r.sdir.hintlist = buftoulong(p);
|
||||
if( rec->r.sdir.lid != recnum ) {
|
||||
log_error_f( db_name, "sdir LID != recnum (%lu,%lu)\n",
|
||||
rec->r.sdir.lid, (ulong)recnum );
|
||||
log_error( "%s: sdir LID != recnum (%lu,%lu)\n",
|
||||
db_name, rec->r.sdir.lid, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
}
|
||||
break;
|
||||
@ -979,8 +1000,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_error_f( db_name, "invalid record type %d at recnum %lu\n",
|
||||
rec->rectype, (ulong)recnum );
|
||||
log_error( "%s: invalid record type %d at recnum %lu\n",
|
||||
db_name, rec->rectype, (ulong)recnum );
|
||||
rc = G10ERR_TRUSTDB;
|
||||
break;
|
||||
}
|
||||
@ -1122,8 +1143,8 @@ tdbio_delete_record( ulong recnum )
|
||||
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
|
||||
rec.recnum = recnum;
|
||||
rec.rectype = RECTYPE_FREE;
|
||||
@ -1149,22 +1170,22 @@ tdbio_new_recnum()
|
||||
/* look for unused records */
|
||||
rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
|
||||
if( rc )
|
||||
log_fatal_f( db_name, _("error reading version record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_fatal( _("%s: error reading version record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
if( vr.r.ver.firstfree ) {
|
||||
recnum = vr.r.ver.firstfree;
|
||||
rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
|
||||
if( rc ) {
|
||||
log_error_f( db_name, _("error reading free record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_error( _("%s: error reading free record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/* update dir record */
|
||||
vr.r.ver.firstfree = rec.r.free.next;
|
||||
rc = tdbio_write_record( &vr );
|
||||
if( rc ) {
|
||||
log_error_f( db_name, _("error writing dir record: %s\n"),
|
||||
g10_errstr(rc) );
|
||||
log_error( _("%s: error writing dir record: %s\n"),
|
||||
db_name, g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
/*zero out the new record */
|
||||
@ -1173,8 +1194,8 @@ tdbio_new_recnum()
|
||||
rec.recnum = recnum;
|
||||
rc = tdbio_write_record( &rec );
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to zero a record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal(_("%s: failed to zero a record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
else { /* not found, append a new record */
|
||||
offset = lseek( db_fd, 0, SEEK_END );
|
||||
@ -1203,8 +1224,8 @@ tdbio_new_recnum()
|
||||
}
|
||||
|
||||
if( rc )
|
||||
log_fatal_f(db_name,_("failed to append a record: %s\n"),
|
||||
g10_errstr(rc));
|
||||
log_fatal(_("%s: failed to append a record: %s\n"),
|
||||
db_name, g10_errstr(rc));
|
||||
}
|
||||
return recnum ;
|
||||
}
|
||||
@ -1230,10 +1251,9 @@ tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec )
|
||||
|
||||
if( !rc ) {
|
||||
if( pk->local_id && pk->local_id != rec->recnum )
|
||||
log_error_f(db_name,
|
||||
"found record, but LID from memory does "
|
||||
log_error("%s: found record, but LID from memory does "
|
||||
"not match recnum (%lu,%lu)\n",
|
||||
pk->local_id, rec->recnum );
|
||||
db_name, pk->local_id, rec->recnum );
|
||||
pk->local_id = rec->recnum;
|
||||
}
|
||||
return rc;
|
||||
@ -1272,8 +1292,8 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
|
||||
/* Now read the dir record */
|
||||
rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
|
||||
if( rc )
|
||||
log_error_f(db_name, "can't read dirrec %lu: %s\n",
|
||||
recnum, g10_errstr(rc) );
|
||||
log_error("%s: can't read dirrec %lu: %s\n",
|
||||
db_name, recnum, g10_errstr(rc) );
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
33
g10/tdbio.h
33
g10/tdbio.h
@ -21,6 +21,7 @@
|
||||
#ifndef G10_TDBIO_H
|
||||
#define G10_TDBIO_H
|
||||
|
||||
#include "host2net.h"
|
||||
|
||||
#define TRUST_RECORD_LEN 40
|
||||
#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
|
||||
@ -46,15 +47,14 @@
|
||||
#define RECTYPE_FREE 254
|
||||
|
||||
|
||||
#define DIRF_CHECKED 1 /* everything has been checked, the other bits are
|
||||
valid */
|
||||
#define DIRF_MISKEY 2 /* not all signatures are checked */
|
||||
/* this flag is used as a quick hint, that we */
|
||||
/* do not need to look at the sig records */
|
||||
#define DIRF_ERROR 4 /* severe errors: the key is not valid for some reasons
|
||||
but we mark it to avoid duplicate checks */
|
||||
#define DIRF_CHECKED 1 /* has been checkd - other bits are valid */
|
||||
#define DIRF_VALID 2 /* This key is valid: There is at least */
|
||||
/* one uid with a selfsignature or an revocation */
|
||||
#define DIRF_EXPIRED 4 /* the complete key has expired */
|
||||
#define DIRF_REVOKED 8 /* the complete key has been revoked */
|
||||
|
||||
#define KEYF_CHECKED 1 /* This key has been checked */
|
||||
#define KEYF_VALID 2 /* This is a valid (sub)key */
|
||||
#define KEYF_EXPIRED 4 /* this key is expired */
|
||||
#define KEYF_REVOKED 8 /* this key has been revoked */
|
||||
|
||||
@ -64,6 +64,7 @@
|
||||
|
||||
#define SIGF_CHECKED 1 /* signature has been checked - bits 0..6 are valid */
|
||||
#define SIGF_VALID 2 /* the signature is valid */
|
||||
#define SIGF_EXPIRED 4 /* the key of this signature has expired */
|
||||
#define SIGF_REVOKED 8 /* this signature has been revoked */
|
||||
#define SIGF_NOPUBKEY 128 /* there is no pubkey for this sig */
|
||||
|
||||
@ -176,22 +177,4 @@ int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
|
||||
int tdbio_search_sdir( u32 *keyid, int pubkey_algo, TRUSTREC *rec );
|
||||
|
||||
|
||||
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
|
||||
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
|
||||
#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
|
||||
#define ulongtobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 24; \
|
||||
((byte*)p)[1] = a >> 16; \
|
||||
((byte*)p)[2] = a >> 8; \
|
||||
((byte*)p)[3] = a ; \
|
||||
} while(0)
|
||||
#define ushorttobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 8; \
|
||||
((byte*)p)[1] = a ; \
|
||||
} while(0)
|
||||
#define buftou32( p) buftoulong( (p) )
|
||||
#define u32tobuf( p, a) ulongtobuf( (p), (a) )
|
||||
|
||||
|
||||
|
||||
#endif /*G10_TDBIO_H*/
|
||||
|
@ -1370,6 +1370,8 @@ update_trustdb( )
|
||||
else
|
||||
log_info("lid %lu: updated\n",
|
||||
lid_from_keyblock(keyblock) );
|
||||
|
||||
release_kbnode( keyblock ); keyblock = NULL;
|
||||
}
|
||||
}
|
||||
if( rc && rc != -1 )
|
||||
@ -1910,7 +1912,6 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
|
||||
}
|
||||
if( recno ) { /* yes */
|
||||
ins_recno_list( recno_list, recno, RECTYPE_KEY );
|
||||
/* here we would compare/update the keyflags */
|
||||
}
|
||||
else { /* no: insert this new key */
|
||||
memset( &krec, 0, sizeof(krec) );
|
||||
@ -2110,6 +2111,8 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
|
||||
}
|
||||
}
|
||||
else if( sig->sig_class == 0x18 ) { /* key binding */
|
||||
/* get the corresponding key */
|
||||
|
||||
/* FIXME */
|
||||
}
|
||||
else if( sig->sig_class == 0x20 ) { /* key revocation */
|
||||
@ -2427,6 +2430,7 @@ update_trust_record( KBNODE keyblock )
|
||||
ulong uidrecno = 0;
|
||||
byte uidhash[20];
|
||||
RECNO_LIST recno_list = NULL; /* list of verified records */
|
||||
/* fixme: replace recno_list by a lookup on node->recno */
|
||||
|
||||
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
|
||||
primary_pk = node->pkt->pkt.public_key;
|
||||
@ -2459,6 +2463,7 @@ update_trust_record( KBNODE keyblock )
|
||||
|
||||
case PKT_SIGNATURE:
|
||||
if( drec.dirty ) { /* upd_sig_recrod may read the drec */
|
||||
|
||||
write_record( &drec );
|
||||
drec.dirty = 0;
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* iobuf.h (iobuf_get_temp_buffer): New.
|
||||
|
||||
Tue Oct 13 12:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* iobuf.h (iobuf_get): Now uses .nofast
|
||||
|
@ -7,6 +7,7 @@ ttyio.h
|
||||
types.h
|
||||
util.h
|
||||
i18n.h
|
||||
host2net.h
|
||||
|
||||
g10lib.h
|
||||
|
||||
|
43
include/host2net.h
Normal file
43
include/host2net.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* host2net.h - Some macros
|
||||
* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNUPG.
|
||||
*
|
||||
* GNUPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GNUPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef G10_HOST2NET_H
|
||||
#define G10_HOST2NET_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
|
||||
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
|
||||
#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
|
||||
#define ulongtobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 24; \
|
||||
((byte*)p)[1] = a >> 16; \
|
||||
((byte*)p)[2] = a >> 8; \
|
||||
((byte*)p)[3] = a ; \
|
||||
} while(0)
|
||||
#define ushorttobuf( p, a ) do { \
|
||||
((byte*)p)[0] = a >> 8; \
|
||||
((byte*)p)[1] = a ; \
|
||||
} while(0)
|
||||
#define buftou32( p) buftoulong( (p) )
|
||||
#define u32tobuf( p, a) ulongtobuf( (p), (a) )
|
||||
|
||||
|
||||
#endif /*G10_HOST2NET_H*/
|
@ -71,6 +71,7 @@ int iobuf_debug_mode;
|
||||
|
||||
IOBUF iobuf_alloc(int usage, size_t bufsize);
|
||||
IOBUF iobuf_temp(void);
|
||||
IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
|
||||
IOBUF iobuf_open( const char *fname );
|
||||
IOBUF iobuf_fopen( const char *fname, const char *mode );
|
||||
IOBUF iobuf_create( const char *fname );
|
||||
@ -129,6 +130,7 @@ int iobuf_in_block_mode( IOBUF a );
|
||||
#define iobuf_where(a) "[don't know]"
|
||||
#define iobuf_id(a) ((a)->no)
|
||||
|
||||
#define iobuf_get_temp_buffer(a) ( (a)->d.buf )
|
||||
#define iobuf_get_temp_length(a) ( (a)->d.len )
|
||||
#define iobuf_is_temp(a) ( (a)->usage == 3 )
|
||||
|
||||
|
@ -9,19 +9,25 @@ if (autoconf --version) < /dev/null > /dev/null 2>&1 ; then
|
||||
else
|
||||
echo
|
||||
echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM."
|
||||
echo ' (version 2.10 or newer is required'
|
||||
echo ' (version 2.10 or newer is required)'
|
||||
DIE="yes"
|
||||
fi
|
||||
|
||||
if (automake --version) < /dev/null > /dev/null 2>&1 ; then
|
||||
if (aclocal --version) < /dev/null > /dev/null 2>&1; then
|
||||
:
|
||||
if (aclocal --version | awk 'NR==1 { if( $4 >= 1.3 ) exit 1; exit 0; }');
|
||||
then
|
||||
echo "**Error**: "\`aclocal\'" is too old."
|
||||
echo ' (version 1.3 or newer is required)'
|
||||
DIE="yes"
|
||||
fi
|
||||
else
|
||||
echo
|
||||
echo "**Error**: Missing "\`aclocal\'". The version of "\`automake\'
|
||||
echo " installed doesn't appear recent enough."
|
||||
DIE="yes"
|
||||
fi
|
||||
|
||||
else
|
||||
echo
|
||||
echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
|
||||
@ -40,3 +46,5 @@ automake --gnu;
|
||||
autoheader
|
||||
autoconf
|
||||
|
||||
echo "Ready to run ./configure"
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
needed_libs = ../cipher/libcipher.a ../util/libutil.a \
|
||||
../mpi/libmpi.a ../util/libutil.a
|
||||
../mpi/libmpi.a ../util/libutil.a @INTLLIBS@
|
||||
|
||||
noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest
|
||||
|
||||
@ -15,10 +15,10 @@ mk_tdata_SOURCES = mk-tdata.c
|
||||
shmtest_SOURCES = shmtest.c
|
||||
|
||||
|
||||
mpicalc_LDADD = @INTLLIBS@ $(needed_libs)
|
||||
bftest_LDADD = @INTLLIBS@ $(needed_libs)
|
||||
mpicalc_LDADD = $(needed_libs)
|
||||
bftest_LDADD = $(needed_libs)
|
||||
|
||||
shmtest_LDADD = @INTLLIBS@ $(needed_libs)
|
||||
shmtest_LDADD = $(needed_libs)
|
||||
|
||||
mpicalc bftest shmtest: $(needed_libs)
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
Wed Oct 21 12:20:29 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* util.c (iobuf_flush): autoincreasing of a temp. iobuf
|
||||
(iobuf_temp_with_content): New.
|
||||
|
||||
Tue Oct 13 12:40:13 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* util.c (.nofast): set this variable
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
|
||||
noinst_LIBRARIES = libutil.a
|
||||
|
||||
|
27
util/iobuf.c
27
util/iobuf.c
@ -483,6 +483,18 @@ iobuf_temp()
|
||||
return a;
|
||||
}
|
||||
|
||||
IOBUF
|
||||
iobuf_temp_with_content( const char *buffer, size_t length )
|
||||
{
|
||||
IOBUF a;
|
||||
|
||||
a = iobuf_alloc(3, length );
|
||||
memcpy( a->d.buf, buffer, length );
|
||||
a->d.len = length;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Create a head iobuf for reading from a file
|
||||
@ -877,8 +889,19 @@ iobuf_flush(IOBUF a)
|
||||
return 0;
|
||||
|
||||
/*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
|
||||
if( a->usage == 3 )
|
||||
log_bug("temp buffer too short\n");
|
||||
if( a->usage == 3 ) { /* must increase the size of the temp buffer */
|
||||
char *newbuf;
|
||||
size_t newsize = a->d.size + 8192;
|
||||
|
||||
log_debug("increasing temp iobuf from %lu to %lu\n",
|
||||
(ulong)a->d.size, (ulong)newsize );
|
||||
newbuf = m_alloc( newsize );
|
||||
memcpy( newbuf, a->d.buf, a->d.len );
|
||||
m_free(a->d.buf);
|
||||
a->d.buf = newbuf;
|
||||
a->d.size = newsize;
|
||||
return 0;
|
||||
}
|
||||
else if( a->usage != 2 )
|
||||
log_bug("flush on non-output iobuf\n");
|
||||
else if( !a->filter )
|
||||
|
@ -161,7 +161,7 @@ g10_log_bug( const char *fmt, ... )
|
||||
va_list arg_ptr ;
|
||||
|
||||
putc('\n', stderr );
|
||||
print_prefix("Ooops: ");
|
||||
print_prefix("Ohhhh jeeee: ");
|
||||
va_start( arg_ptr, fmt ) ;
|
||||
vfprintf(stderr,fmt,arg_ptr) ;
|
||||
va_end(arg_ptr);
|
||||
@ -174,7 +174,7 @@ g10_log_bug( const char *fmt, ... )
|
||||
void
|
||||
g10_log_bug0( const char *file, int line, const char *func )
|
||||
{
|
||||
log_bug(_("Ohhhh jeeee ... this is a bug (%s:%d:%s)\n"), file, line, func );
|
||||
log_bug(_("... this is a bug (%s:%d:%s)\n"), file, line, func );
|
||||
}
|
||||
#else
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user