aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--acinclude.m4112
-rw-r--r--cipher/ChangeLog4
-rw-r--r--cipher/md.c13
-rw-r--r--configure.in7
-rw-r--r--doc/Makefile.am33
-rw-r--r--doc/gcryptref.sgml33
-rw-r--r--doc/version.sgml.in1
-rw-r--r--g10/ChangeLog8
-rw-r--r--g10/Makefile.am7
-rw-r--r--g10/build-packet.c1
-rw-r--r--g10/kbx.h6
-rw-r--r--g10/kbxblob.c240
-rw-r--r--g10/kbxfile.c45
-rw-r--r--g10/keydb.h3
-rw-r--r--g10/packet.h2
-rw-r--r--g10/ringedit.c519
-rwxr-xr-xscripts/db2html.in151
-rw-r--r--tools/Makefile.am6
19 files changed, 1039 insertions, 156 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e84473d9..e0091e20c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <[email protected]>
+
+ * configure.in: Now uses the Docbook M$s from GPH.
+
Mon Jan 31 17:46:35 CET 2000 Werner Koch <wk@>
* Makefile.am: Re-added tools. By R�mi.
diff --git a/acinclude.m4 b/acinclude.m4
index 4a8f0a2b2..20c92be52 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -663,4 +663,116 @@ if test $gnupg_cv_mkdir_takes_one_arg = yes ; then
fi
])
+
+dnl GPH_PROG_DOCBOOK()
+dnl Check whether we have the needed Docbook environment
+dnl and issue a warning if this is not the case.
+dnl
+dnl This test defines these variables for substitution:
+dnl DB2HTML - command used to convert Docbook to HTML
+dnl DB2TEX - command used to convert Docbook to TeX
+dnl DB2MAN - command used to convert Docbook to man pages
+dnl JADE - command to invoke jade
+dnl JADETEX - command to invoke jadetex
+dnl DSL_FOR_HTML - the stylesheet used to for the Docbook->HTML conversion
+dnl The following make conditionals are defined
+dnl HAVE_DB2MAN - defined when db2man is available
+dnl HAVE_DB2TEX - defined when db2tex is available
+dnl HAVE_DB2HTML - defined when db2html is available
+dnl HAVE_DOCBOOK - defined when the entire Docbook environment is present
+dnl HAVE_JADE - defined when jade is installed
+dnl HAVE_JADETEX - defined when jadetex is installed
+dnl
+dnl (wk 2000-02-17)
+dnl
+AC_DEFUN(GPH_PROG_DOCBOOK,
+ [ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+ all=yes
+ AC_PATH_PROG(DB2MAN, docbook-to-man, no)
+ test "$DB2MAN" = no && all=no
+ AM_CONDITIONAL(HAVE_DB2MAN, test "$DB2MAN" != no )
+
+ AC_PATH_PROG(JADE, jade, no)
+ test "$JADE" = no && all=no
+ AM_CONDITIONAL(HAVE_JADE, test "$JADE" != no )
+
+ AC_PATH_PROG(JADETEX, jadetex, no)
+ test "$JADETEX" = no && all=no
+ AM_CONDITIONAL(HAVE_JADETEX, test "$JADETEX" != no )
+
+ stylesheet_dirs='
+/usr/local/lib/dsssl/stylesheets/docbook
+/usr/local/share/dsssl/stylesheets/docbook
+/usr/local/lib/sgml/stylesheet/dsssl/docbook/nwalsh
+/usr/local/share/sgml/stylesheet/dsssl/docbook/nwalsh
+/usr/lib/dsssl/stylesheets/docbook
+/usr/share/dsssl/stylesheets/docbook
+/usr/lib/sgml/stylesheet/dsssl/docbook/nwalsh
+/usr/share/sgml/stylesheet/dsssl/docbook/nwalsh
+'
+
+ AC_MSG_CHECKING(for TeX stylesheet)
+ dsl=none
+ for d in ${stylesheet_dirs}; do
+ file=${d}/print/docbook.dsl
+ if test -f $file; then
+ dsl=$file
+ break
+ fi
+ done
+ AC_MSG_RESULT([$dsl])
+ okay=no
+ if test $dsl = none ; then
+ DB2TEX="$missing_dir/missing db2tex"
+ all=no
+ else
+ DB2TEX="$JADE -t tex -i tex -d $dsl"
+ okay=yes
+ fi
+ AC_SUBST(DB2TEX)
+ AM_CONDITIONAL(HAVE_DB2TEX, test $okay = yes )
+
+ if ( $ac_aux_dir/db2html.in --version) < /dev/null > /dev/null 2>&1; then
+ :
+ else
+ AC_ERROR([needed $ac_aux_dir/db2html.in not found])
+ fi
+
+ AC_MSG_CHECKING(for HTML stylesheet)
+ DSL_FOR_HTML="none"
+ for d in ${stylesheet_dirs}; do
+ file=${d}/html/docbook.dsl
+ if test -f $file; then
+ DSL_FOR_HTML=$file
+ break
+ fi
+ done
+ AC_MSG_RESULT([$DSL_FOR_HTML])
+ okay=no
+ if test $DSL_FOR_HTML = none ; then
+ DB2HTML="$missing_dir/missing db2html"
+ all=no
+ else
+ DB2HTML="`cd $ac_aux_dir && pwd`/db2html --copyfiles"
+ okay=yes
+ fi
+ AC_SUBST(DB2HTML)
+ AC_SUBST(DSL_FOR_HTML)
+ AM_CONDITIONAL(HAVE_DB2HTML, test $okay = yes )
+
+ AM_CONDITIONAL(HAVE_DOCBOOK, test "$all" != yes )
+ if test $all = no ; then
+ AC_MSG_WARN([[
+***
+*** It seems that the Docbook environment is not installed as required.
+*** We will try to build everything, but if you either touch some files
+*** or use a bogus make tool, you may run into problems.
+*** Docbook is normally only needed to build the documentation.
+***]])
+ fi
+ ])
+
+
+
+
dnl *-*wedit:notab*-* Please keep this as the last line.
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index c0657d727..a81189702 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,7 @@
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <[email protected]>
+
+ * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
+
Mon Jan 31 16:37:34 CET 2000 Werner Koch <[email protected]>
* genprime.c (generate_elg_prime): Fixed returned factors which never
diff --git a/cipher/md.c b/cipher/md.c
index bc0a6c30d..680558db2 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -596,15 +596,22 @@ gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen )
* Shortcut function to hash a buffer with a given algo. The only supported
* algorithm is RIPE-MD. The supplied digest buffer must be large enough
* to store the resulting hash. No error is returned, the function will
- * abort on an invalite algo. DISABLED_ALGOS are ignored here.
+ * abort on an invalid algo. DISABLED_ALGOS are ignored here.
*/
void
gcry_md_hash_buffer( int algo, char *digest, const char *buffer, size_t length)
{
if( algo == GCRY_MD_RMD160 )
rmd160_hash_buffer( digest, buffer, length );
- else
- BUG();
+ else { /* for the others we do not have a fast function, so
+ * we use the normal functions to do it */
+ GCRY_MD_HD h = md_open( algo, 0 );
+ if( !h )
+ BUG(); /* algo not available */
+ md_write( h, (byte*)buffer, length );
+ md_final( h );
+ memcpy( digest, md_read( h, algo ), md_digest_length( algo ) );
+ }
}
static int
diff --git a/configure.in b/configure.in
index ac926d640..fddb93d2a 100644
--- a/configure.in
+++ b/configure.in
@@ -164,8 +164,7 @@ AC_PROG_CPP
AC_ISC_POSIX
AC_PROG_INSTALL
AC_PROG_AWK
-AC_CHECK_PROG(DOCBOOK_TO_MAN, docbook-to-man, yes, no)
-AM_CONDITIONAL(HAVE_DOCBOOK_TO_MAN, test "$ac_cv_prog_DOCBOOK_TO_MAN" = yes)
+GPH_PROG_DOCBOOK
dnl
@@ -687,6 +686,7 @@ GNUPG_FIX_HDR_VERSION(gcrypt/gcrypt.h, GCRYPT_VERSION)
AC_OUTPUT_COMMANDS([
+chmod +x scripts/db2html
chmod +x gcrypt/gcrypt-config
cat >gnupg-defs.tmp <<G10EOF
/* Generated automatically by configure */
@@ -719,6 +719,7 @@ DATADIRNAME=$DATADIRNAME
AC_OUTPUT([
Makefile
+scripts/db2html
intl/Makefile
po/Makefile.in
jnlib/Makefile
@@ -727,7 +728,7 @@ mpi/Makefile
cipher/Makefile
g10/Makefile
doc/Makefile
-doc/gph/Makefile
+doc/version.sgml
tools/Makefile
zlib/Makefile
checks/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 04ad0a4c7..995b0b3db 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,33 +1,40 @@
## Process this file with automake to create Makefile.in
-EXTRA_DIST = DETAILS gpg.sgml gpg.1 FAQ HACKING OpenPGP
+EXTRA_DIST = DETAILS gpg.sgml gpg.1 FAQ HACKING OpenPGP \
+ version.sgml.in
man_MANS = gpg.1
+pkgdata_DATA = gcryptref.html gcryptref.ps
-gcryptref.dvi : gcryptref.sgml
+BUILT_SOURCES = version.sgml gcryptref.html gcryptref.ps
-gcryptref.texi : gcryptref.sgml
-gcryptref.xml : gcryptref.sgml
+CLEANFILES = gcryptref.aux gcryptref.log gcryptref.tex gcryptref.dvi
-%.ps: %.dvi
- dvips -o $@ $<
-
+gcryptref.sgml : version.sgml
-if MAINTAINER_MODE
+if HAVE_DB2MAN
%.1 : %.sgml
- docbook-to-man $< >$@
+ $(DB2MAN) $< >$@
+endif
-%.texi : %.xml
- docbook2texi $< >$@
+if HAVE_DB2TEX
+%.ps : %.dvi
+ dvips -o $@ $<
-%.xml : %.sgml
- sgml2xml -x lower $< >$@
+%.tex : %.sgml
+ $(DB2TEX) -V generate-book-toc $< > $@
+%.dvi : %.tex
+ $(JADETEX) $<
endif
+if HAVE_DB2HTML
+%.html : %.sgml
+ $(DB2HTML) --nosplit $<
+endif
diff --git a/doc/gcryptref.sgml b/doc/gcryptref.sgml
index abc3efb20..bf9d5092d 100644
--- a/doc/gcryptref.sgml
+++ b/doc/gcryptref.sgml
@@ -18,7 +18,9 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-->
-<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
+<!--entity genindex system "gcryptref.toc-idx"-->
+<!entity packageversion system "version.sgml">
<!entity libgcrypt "Libgcrypt">
<!entity sexp "S-Exp">
<!entity cipherref system "gcryptref-cipher.sgml">
@@ -27,6 +29,33 @@
<!entity miscref system "gcryptref-misc.sgml">
]>
+<book>
+<bookinfo>
+<title>The &libgcrypt; Reference Manual</title>
+<subtitle>Version &packageversion;</subtitle>
+<date>
+2000-03-13
+</date>
+<copyright>
+<year>2000</year>
+<holder>Free Software Foundation, Inc.</holder>
+</copyright>
+<abstract>
+<para>
+Please direct questions, bug reports, or suggestions concerning
+this manual to the mailing list <email>[email protected]</email>.
+</para>
+
+<para>
+This manual may be redistributed under the terms of the
+<ulink url="http://www.gnu.org/copyleft/gpl.html"><phrase>GNU
+General Public License</phrase></ulink>.
+</para>
+</abstract>
+</bookinfo>
+
+
+
<reference>
<title>&libgcrypt; Reference Pages</title>
@@ -37,7 +66,7 @@
<!-- Hash Functions -->
&digestref;
-<!-- ublic Key Functions -->
+<!-- Public Key Functions -->
&pubkeyref;
<!-- Miscellaneous Functions -->
diff --git a/doc/version.sgml.in b/doc/version.sgml.in
new file mode 100644
index 000000000..d78bda934
--- /dev/null
+++ b/doc/version.sgml.in
@@ -0,0 +1 @@
+@VERSION@
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 21b24880e..6cd97d675 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,11 @@
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <[email protected]>
+
+ * build-paket.c (do_user_id): Save offset where name has been stored.
+
+ * ringedit.c : Add new access method KBXF
+
+ * kbxfile.c: New.
+
Mon Feb 21 22:43:01 CET 2000 Werner Koch <wk@>
* kbx.h: New.
diff --git a/g10/Makefile.am b/g10/Makefile.am
index bc83ad9c2..9018c1450 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -4,7 +4,9 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
EXTRA_DIST = OPTIONS pubring.asc options.skel
OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = -static @LDFLAGS@ @DYNLINK_LDFLAGS@
-needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la ../jnlib/libjnlib.la
+# we need to add libutil.la a second time because we have to resolve
+# gpg_log_ in some libjnlib modules. - very ugly - should be removed soon.
+needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la ../jnlib/libjnlib.la ../util/libutil.la
#noinst_PROGRAMS = gpgd
bin_PROGRAMS = gpg
@@ -22,6 +24,9 @@ common_source = \
skclist.c \
ringedit.c \
kbnode.c \
+ kbx.h \
+ kbxblob.c \
+ kbxfile.c \
main.h \
mainproc.c \
armor.c \
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 2f3eebea3..5772b13be 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -196,6 +196,7 @@ static int
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
{
write_header(out, ctb, uid->len);
+ uid->stored_at = iobuf_tell( out ); /* what a hack */
if( iobuf_write( out, uid->name, uid->len ) )
return GPGERR_WRITE_FILE;
return 0;
diff --git a/g10/kbx.h b/g10/kbx.h
index 9e61ebbd0..6508d3eab 100644
--- a/g10/kbx.h
+++ b/g10/kbx.h
@@ -21,6 +21,12 @@
#ifndef GPG_KBX_H
#define GPG_KBX_H 1
+#include "keydb.h"
+
+typedef struct kbxblob *KBXBLOB;
+
+int kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock );
+void kbx_release_blob ( KBXBLOB blob );
#endif /*GPG_KBX_H*/
diff --git a/g10/kbxblob.c b/g10/kbxblob.c
index cf3bb7a22..c7804870c 100644
--- a/g10/kbxblob.c
+++ b/g10/kbxblob.c
@@ -16,27 +16,6 @@
* 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
- *
- ***********************************************
- * adler_cksum() is based on the zlib code with these conditions:
- *
- * Copyright (C) 1995-1998 Mark Adler
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
*/
@@ -51,9 +30,11 @@ the beginning of the Blob.
The first record of a plain KBX file has a special format:
u32 length of the first record
- u32 magic 'KBXf'
+ byte Blob type (1)
byte version number (1)
- b[3] reserved
+ byte reserved
+ byte reserved
+ u32 magic 'KBXf'
byte marginals used for validity calculation of this file
byte completes ditto.
byte cert_depth ditto.
@@ -61,8 +42,8 @@ The first record of a plain KBX file has a special format:
The standard KBX Blob looks like this:
u32 length of this blob (including these 4 bytes)
- byte version number (1)
- byte reserved
+ byte Blob type (2)
+ byte version number of this blob type (1)
u16 Blob flags
bit 0 = contains secret key material
@@ -98,6 +79,8 @@ The standard KBX Blob looks like this:
u8 all_validity
u16 reserved
u32 recheck_after
+ u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
+ u32 Blob created at
u32 size of reserved space (not including this field)
reserved space
@@ -107,7 +90,7 @@ The standard KBX Blob looks like this:
maybe we put a sigture here later.
- u32 adler checksum
+ b16 MD5 checksum (useful for KS syncronsiation)
*
*/
@@ -120,6 +103,8 @@ The standard KBX Blob looks like this:
#include <assert.h>
#include <gcrypt.h>
+#include "iobuf.h"
+#include "util.h"
#include "kbx.h"
/* special values of the signature status */
@@ -135,22 +120,21 @@ The standard KBX Blob looks like this:
struct kbxblob_key {
char fpr[20];
u32 off_kid;
- ulong off_kid_addr; /* where it is stored in the datablock */
+ ulong off_kid_addr;
u16 flags;
};
struct kbxblob_uid {
- u32 off;
- ulong off_addr; /* where it is stored in the datablock */
+ ulong off_addr;
u32 len;
u16 flags;
- byte validity
+ byte validity;
};
struct keyid_list {
struct keyid_list *next;
int seqno;
- char kid[8];
-}
+ byte kid[8];
+};
struct kbxblob {
int nkeys;
@@ -161,49 +145,10 @@ struct kbxblob {
u32 *sigs;
struct keyid_list *temp_kids;
-} *KBXBLOB;
+ IOBUF buf; /* the KBX is stored here */
+};
-static u32
-adler_cksum ( const byte *buf, size_t len )
-{
- unsigned long s1 = 1;
- unsigned long s2 = 0;
-
- #define X_BASE 65521L /* largest prime smaller than 65536 */
- #define X_NMAX 5552 /* largest n such that */
- /* 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
- #define X_DO1(buf,i) {s1 += buf[i]; s2 += s1;}
- #define X_DO2(buf,i) X_DO1(buf,i); X_DO1(buf,i+1);
- #define X_DO4(buf,i) X_DO2(buf,i); X_DO2(buf,i+2);
- #define X_DO8(buf,i) X_DO4(buf,i); X_DO4(buf,i+4);
- #define X_DO16(buf) X_DO8(buf,0); X_DO8(buf,8);
- while ( len ) {
- int k = len < NMAX ? len : NMAX;
- len -= k;
- while ( k >= 16 ) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if ( k ) {
- do {
- s1 += *buf++;
- s2 += s1;
- } while ( --k );
- }
- s1 %= BASE;
- s2 %= BASE;
- }
- #undef X_BASE
- #undef X_NMAX
- #undef X_DO1
- #undef X_DO2
- #undef X_DO4
- #undef X_DO8
- #undef X_DO16
- return ( s2 << 16 ) | s1;
-}
/* Note: this functions are only used for temportay iobufs and therefore
@@ -211,14 +156,14 @@ adler_cksum ( const byte *buf, size_t len )
static void
put8 ( IOBUF out, byte a )
{
- iobuf_put ( out, a )
+ iobuf_put ( out, a );
}
static void
put16 ( IOBUF out, u16 a )
{
iobuf_put ( out, a>>8 );
- iobuf_put ( out, a )
+ iobuf_put ( out, a );
}
static void
@@ -227,7 +172,7 @@ put32 ( IOBUF out, u32 a )
iobuf_put (out, a>> 24);
iobuf_put (out, a>> 16);
iobuf_put (out, a>> 8);
- iobuf_put (out, a) )
+ iobuf_put (out, a );
}
static void
@@ -245,7 +190,7 @@ static void
put32at ( IOBUF out, u32 a, size_t pos )
{
size_t n;
- byte *p,
+ byte *p;
iobuf_flush_temp ( out );
p = iobuf_get_temp_buffer( out );
@@ -269,37 +214,44 @@ temp_store_kid ( KBXBLOB blob, PKT_public_key *pk )
struct keyid_list *k, *r;
k = gcry_xmalloc ( sizeof *k );
- k->kid = pk->keyid;
+ k->kid[0] = pk->keyid[0] >> 24 ;
+ k->kid[1] = pk->keyid[0] >> 16 ;
+ k->kid[2] = pk->keyid[0] >> 8 ;
+ k->kid[3] = pk->keyid[0] ;
+ k->kid[4] = pk->keyid[0] >> 24 ;
+ k->kid[5] = pk->keyid[0] >> 16 ;
+ k->kid[6] = pk->keyid[0] >> 8 ;
+ k->kid[7] = pk->keyid[0] ;
k->seqno = 0;
k->next = blob->temp_kids;
blob->temp_kids = k;
for ( r=k; r; r = r->next ) {
- k->seqno++
+ k->seqno++;
}
return k->seqno;
}
static void
-put_stored_kid( IOBUF a, KBXBLOB blob, int seqno )
+put_stored_kid( KBXBLOB blob, int seqno )
{
struct keyid_list *r;
for ( r = blob->temp_kids; r; r = r->next ) {
if( r->seqno == seqno ) {
- putn ( a, r->kid, 8 );
+ putn ( blob->buf, r->kid, 8 );
return;
}
}
BUG();
}
-static int
+static void
release_kid_list ( struct keyid_list *kl )
{
struct keyid_list *r, *r2;
- for ( r = blob->temp_kids; r; r = r2 ) {
+ for ( r = kl; r; r = r2 ) {
r2 = r->next;
gcry_free( r );
}
@@ -310,19 +262,18 @@ static int
create_key_part( KBXBLOB blob, KBNODE keyblock )
{
KBNODE node;
- byte fpr[MAX_FINGERPRINT_LEN];
size_t fprlen;
int n;
for ( n=0, node = keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY:
+ if ( node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
PKT_public_key *pk = node->pkt->pkt.public_key;
fingerprint_from_pk( pk, blob->keys[n].fpr, &fprlen );
if ( fprlen != 20 ) { /*v3 fpr - shift right and fill with zeroes*/
assert( fprlen == 16 );
- memmove( blob->keys[n]+4, blob->keys[n].fpr, 16);
+ memmove( blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
memset( blob->keys[n].fpr, 0, 4 );
blob->keys[n].off_kid = temp_store_kid( blob, pk );
}
@@ -351,7 +302,6 @@ create_uid_part( KBXBLOB blob, KBNODE keyblock )
if ( node->pkt->pkttype == PKT_USER_ID ) {
PKT_user_id *u = node->pkt->pkt.user_id;
- blob->uids[n].off = 0; /* must calculate this later */
blob->uids[n].len = u->len;
blob->uids[n].flags = 0;
blob->uids[n].validity = 0;
@@ -382,13 +332,14 @@ create_sig_part( KBXBLOB blob, KBNODE keyblock )
static int
-create_blob_header( IOBUF a, KBXBLOB blob )
+create_blob_header( KBXBLOB blob )
{
+ IOBUF a = blob->buf;
int i;
put32 ( a, 0 ); /* blob length, needs fixup */
- put8 ( a, 1 ); /* version number */
- put8 ( a, 0 ); /* reserved */
+ put8 ( a, 2 ); /* blob type */
+ put8 ( a, 1 ); /* blob type version */
put16 ( a, 0 ); /* blob flags */
put32 ( a, 0 ); /* offset to the keyblock, needs fixup */
@@ -398,7 +349,7 @@ create_blob_header( IOBUF a, KBXBLOB blob )
put16 ( a, 20 + 8 + 2 + 2 ); /* size of key info */
for ( i=0; i < blob->nkeys; i++ ) {
putn ( a, blob->keys[i].fpr, 20 );
- blob->keys[i].off_kid_addr = iobuf_tell ( out );
+ blob->keys[i].off_kid_addr = iobuf_tell ( a );
put32 ( a, 0 ); /* offset to keyid, fixed up later */
put16 ( a, blob->keys[i].flags );
put16 ( a, 0 ); /* reserved */
@@ -407,7 +358,7 @@ create_blob_header( IOBUF a, KBXBLOB blob )
put16 ( a, blob->nuids );
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
for ( i=0; i < blob->nuids; i++ ) {
- blob->uids[i].off_addr = iobuf_tell ( out );
+ blob->uids[i].off_addr = iobuf_tell ( a );
put32 ( a, 0 ); /* offset to userid, fixed up later */
put32 ( a, blob->uids[i].len );
put16 ( a, blob->uids[i].flags );
@@ -425,16 +376,18 @@ create_blob_header( IOBUF a, KBXBLOB blob )
put8 ( a, 0 ); /* validity of all user IDs */
put16 ( a, 0 ); /* reserved */
put32 ( a, 0 ); /* time of next recheck */
+ put32 ( a, 0 ); /* newest timestamp (none) */
+ put32 ( a, make_timestamp() ); /* creation time */
put32 ( a, 0 ); /* size of reserved space */
- /* reserved space (which is currently 0) */
+ /* reserved space (which is currently of size 0) */
/* We need to store the keyids for all v3 keys because those key IDs are
* not part of the fingerprint. While we are doing that, we fixup all
* the keyID offsets */
for ( i=0; i < blob->nkeys; i++ ) {
if ( blob->keys[i].off_kid ) { /* this is a v3 one */
- put32at ( a, iobuf_tell(), blob->keys[i].off_kid_addr );
- put_stored_kid ( a, blob, blob->keys[i].off_kid );
+ put32at ( a, iobuf_tell(a), blob->keys[i].off_kid_addr );
+ put_stored_kid ( blob, blob->keys[i].off_kid );
}
else { /* the better v4 key IDs - just store an offset 8 bytes back */
put32at ( a, blob->keys[i].off_kid_addr-8,
@@ -447,38 +400,60 @@ create_blob_header( IOBUF a, KBXBLOB blob )
}
static int
-create_blob_keyblock( IOBUF a, KBXBLOB blob, KBNODE keyblock )
+create_blob_keyblock( KBXBLOB blob, KBNODE keyblock )
{
+ IOBUF a = blob->buf;
KBNODE node;
int rc;
+ int nsig;
- for ( node = keyblock; node; node = node->next ) {
- /* we must get some offset into thge keyblock and do some
- * fixups */
- rc = build_packet ( fp, node->pkt );
+ for ( nsig = 0, node = keyblock; node; node = node->next ) {
+ rc = build_packet ( a, node->pkt );
if ( rc ) {
- log_error("build_packet(%d) for kbxblob failed: %s\n",
+ gpg_log_error("build_packet(%d) for kbxblob failed: %s\n",
node->pkt->pkttype, gpg_errstr(rc) );
return GPGERR_WRITE_FILE;
}
+ if ( node->pkt->pkttype == PKT_USER_ID ) {
+ PKT_user_id *u = node->pkt->pkt.user_id;
+ /* build_packet has set the offset of the name into u ;
+ * now we can do the fixup */
+ put32at ( a, u->stored_at, blob->uids[nsig].off_addr );
+ nsig++;
+ }
}
+ assert( nsig == blob->nsigs );
return 0;
}
static int
-create_blob_trailer( IOBUF a, KBXBLOB blob )
+create_blob_trailer( KBXBLOB blob )
{
+ IOBUF a = blob->buf;
return 0;
}
static int
-create_blob_finish( IOBUF a, KBXBLOB blob )
+create_blob_finish( KBXBLOB blob )
{
+ IOBUF a = blob->buf;
+ byte *p;
+ size_t n;
+ /* write a placeholder for the checksum */
+ put32( a, 0 ); put32( a, 0 ); put32( a, 0 ); put32( a, 0 );
+ /* get the memory area */
+ iobuf_flush_temp ( a );
+ p = iobuf_get_temp_buffer ( a );
+ n = iobuf_get_temp_length ( a );
+ assert( n >= 20 );
/* fixup the length */
- /* optionally we could sign the whole stuff at this point */
- /* write the checksum */
+ put32at ( a, 0, n );
+
+ /* calculate and store the MD5 checksum */
+ gcry_md_hash_buffer( GCRY_MD_MD5, p + n - 16, p, n - 16 );
+
return 0;
}
@@ -488,9 +463,7 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
{
int rc = 0;
KBNODE node;
- struct kbxblob *blob;
- int nkey, nuid, nsig;
- IOBUF a = NULL;
+ KBXBLOB blob;
*retkbx = NULL;
blob = gcry_calloc (1, sizeof *blob );
@@ -507,56 +480,63 @@ kbx_create_blob ( KBXBLOB *retkbx, KBNODE keyblock )
case PKT_PUBLIC_SUBKEY:
case PKT_SECRET_SUBKEY: blob->nkeys++; break;
case PKT_USER_ID: blob->nuids++; break;
- case PKT_SIGNATURE: blob->nsigs++, break;
+ case PKT_SIGNATURE: blob->nsigs++; break;
+ default: break;
}
}
- blob->nkeys = gcry_calloc ( blob->nkeys, sizeof ( blob->keys ) );
- blob->nuids = gcry_calloc ( blob->nuids, sizeof ( blob->uids ) );
- blob->nsigs = gcry_calloc ( blob->nsigs, sizeof ( blob->sigs ) );
- if ( !blob->nkeys || !blob->nuids || !blob->nsigs ) {
+ blob->keys = gcry_calloc ( blob->nkeys, sizeof ( blob->keys ) );
+ blob->uids = gcry_calloc ( blob->nuids, sizeof ( blob->uids ) );
+ blob->sigs = gcry_calloc ( blob->nsigs, sizeof ( blob->sigs ) );
+ if ( !blob->keys || !blob->uids || !blob->sigs ) {
rc = GCRYERR_NO_MEM;
goto leave;
}
- rc = create_key_part ( blob, keyblock ),
+ rc = create_key_part ( blob, keyblock );
if( rc )
goto leave;
- rc = create_uid_part ( blob, keyblock ),
+ rc = create_uid_part ( blob, keyblock );
if( rc )
goto leave;
- rc = create_sig_part ( blob, keyblock ),
+ rc = create_sig_part ( blob, keyblock );
if( rc )
goto leave;
- a = iobuf_temp();
- rc = create_blob_header ( a, blob );
+ blob->buf = iobuf_temp();
+ rc = create_blob_header ( blob );
if( rc )
goto leave;
- rc = create_blob_keyblock ( a, blob, keyblock );
+ rc = create_blob_keyblock ( blob, keyblock );
if( rc )
goto leave;
- rc = create_blob_trailer ( a, blob );
+ rc = create_blob_trailer ( blob );
if( rc )
goto leave;
- rc = create_blob_finish ( a, blob );
+ rc = create_blob_finish ( blob );
if( rc )
goto leave;
- /* now we take the iobuf and copy it to the output */
-
*retkbx = blob;
- failure:
- if( a )
- iobuf_cancel( a );
+ leave:
release_kid_list( blob->temp_kids );
+ blob->temp_kids = NULL;
if ( rc ) {
- gcry_free( blob->nkeys );
- gcry_free( blob->nuids );
- gcry_free( blob->nsigs );
- gcry_free( blob );
+ kbx_release_blob ( blob );
}
return rc;
}
+void
+kbx_release_blob ( KBXBLOB blob )
+{
+ if( !blob )
+ return;
+ if( blob->buf )
+ iobuf_cancel( blob->buf );
+ gcry_free( blob->keys );
+ gcry_free( blob->uids );
+ gcry_free( blob->sigs );
+ gcry_free( blob );
+}
diff --git a/g10/kbxfile.c b/g10/kbxfile.c
new file mode 100644
index 000000000..215259ee4
--- /dev/null
+++ b/g10/kbxfile.c
@@ -0,0 +1,45 @@
+/* kbxfile.c - KBX file handling
+ * Copyright (C) 2000 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
+ */
+
+/****************
+ * We will change the whole system to use only KBX. This file here
+ * will implements the methods needed to operate on plain KBXfiles.
+ * Most stuff from getkey and ringedit will be replaced by stuff here.
+ * To make things even mor easier we will only allow one updateable kbxfile
+ * and optionally some read-only files.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <gcrypt.h>
+
+#include "kbx.h"
+
+
+int
+kbxfile_search_by_fpr( void )
+{
+ return -1;
+}
+
diff --git a/g10/keydb.h b/g10/keydb.h
index 221c01c64..05aac77d3 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -57,7 +57,8 @@ struct kbnode_struct {
enum resource_type {
rt_UNKNOWN = 0,
rt_RING = 1,
- rt_GDBM = 2
+ rt_GDBM = 2,
+ rt_KBXF = 3
};
diff --git a/g10/packet.h b/g10/packet.h
index 495871cf2..02f701799 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -162,6 +162,8 @@ typedef struct {
} PKT_comment;
typedef struct {
+ ulong stored_at; /* the stream offset where it was stored
+ * by build-packet */
int len; /* length of the name */
char name[1];
} PKT_user_id;
diff --git a/g10/ringedit.c b/g10/ringedit.c
index df51be695..2fa79fd74 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -60,6 +60,7 @@
#include "options.h"
#include "main.h"
#include "i18n.h"
+#include "kbx.h"
#ifdef MKDIR_TAKES_ONE_ARG
@@ -96,6 +97,12 @@ 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 );
+static int do_kbxf_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf,
+ const char *fname );
+static int do_kbxf_read( KBPOS *kbpos, KBNODE *ret_root );
+static int do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
+static int do_kbxf_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,
@@ -206,6 +213,7 @@ add_keyblock_resource( const char *url, int force, int secret )
/* Do we have an URL?
* gnupg-gdbm:filename := this is a GDBM resource
+ * gnupg-kbxf:filename := this is a KBX file resource
* gnupg-ring:filename := this is a plain keyring
* filename := See what is is, but create as plain keyring.
*/
@@ -214,6 +222,10 @@ add_keyblock_resource( const char *url, int force, int secret )
rt = rt_RING;
resname += 11;
}
+ else if( !strncmp( resname, "gnupg-kbxf:", 11 ) ) {
+ rt = rt_KBXF;
+ resname += 11;
+ }
else if( !strncmp( resname, "gnupg-gdbm:", 11 ) ) {
rt = rt_GDBM;
resname += 11;
@@ -259,8 +271,17 @@ add_keyblock_resource( const char *url, int force, int secret )
rt = rt_GDBM;
else if( magic == 0xce9a5713 )
log_error("%s: endianess does not match\n", url );
- else
+ else {
+ char buf[8];
+
rt = rt_RING;
+ if( fread( buf, 8, 1, fp) == 1 ) {
+ if( !memcmp( buf+4, "KBXf", 4 )
+ && buf[0] == 1 && buf[1] == 1 ) {
+ rt = rt_KBXF;
+ }
+ }
+ }
}
else /* maybe empty: assume ring */
rt = rt_RING;
@@ -277,6 +298,7 @@ add_keyblock_resource( const char *url, int force, int secret )
goto leave;
case rt_RING:
+ case rt_KBXF:
iobuf = iobuf_open( filename );
if( !iobuf && !force ) {
rc = GPGERR_OPEN_FILE;
@@ -341,6 +363,7 @@ add_keyblock_resource( const char *url, int force, int secret )
#endif
break;
+
#ifdef HAVE_LIBGDBM
case rt_GDBM:
resource_table[i].dbf = gdbm_open( filename, 0,
@@ -458,6 +481,10 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
rc = keyring_search( pkt, kbpos, resource_table[i].iobuf,
resource_table[i].fname );
break;
+ case rt_KBXF:
+ rc = do_kbxf_search( pkt, kbpos, resource_table[i].iobuf,
+ resource_table[i].fname );
+ break;
#ifdef HAVE_LIBGDBM
case rt_GDBM: {
PKT_public_key *req_pk = pkt->pkt.public_key;
@@ -706,6 +733,8 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
switch( kbpos->rt ) {
case rt_RING:
return keyring_read( kbpos, ret_root );
+ case rt_KBXF:
+ return do_kbxf_read( kbpos, ret_root );
#ifdef HAVE_LIBGDBM
case rt_GDBM:
return do_gdbm_read( kbpos, ret_root );
@@ -762,6 +791,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
kbpos->valid = 0;
switch( kbpos->rt ) {
case rt_RING:
+ case rt_KBXF:
kbpos->fp = iobuf_open( rentry->fname );
if( !kbpos->fp ) {
log_error("can't open `%s'\n", rentry->fname );
@@ -788,6 +818,11 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
return GPGERR_GENERAL;
rc = keyring_enum( kbpos, ret_root, mode == 11 );
break;
+ case rt_KBXF:
+ if( !kbpos->fp )
+ return GPGERR_GENERAL;
+ rc = do_kbxf_enum( kbpos, ret_root, mode == 11 );
+ break;
#ifdef HAVE_LIBGDBM
case rt_GDBM:
rc = do_gdbm_enum( kbpos, ret_root );
@@ -812,6 +847,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
else {
switch( kbpos->rt ) {
case rt_RING:
+ case rt_KBXF:
if( kbpos->fp ) {
iobuf_close( kbpos->fp );
kbpos->fp = NULL;
@@ -852,6 +888,9 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
case rt_RING:
rc = keyring_copy( kbpos, 1, root );
break;
+ case rt_KBXF:
+ rc = do_kbxf_copy( kbpos, 1, root );
+ break;
#ifdef HAVE_LIBGDBM
case rt_GDBM:
rc = do_gdbm_store( kbpos, root, 0 );
@@ -881,6 +920,9 @@ delete_keyblock( KBPOS *kbpos )
case rt_RING:
rc = keyring_copy( kbpos, 2, NULL );
break;
+ case rt_KBXF:
+ rc = do_kbxf_copy( kbpos, 2, NULL );
+ break;
#ifdef HAVE_LIBGDBM
case rt_GDBM:
log_debug("deleting gdbm keyblock is not yet implemented\n");
@@ -909,6 +951,9 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
case rt_RING:
rc = keyring_copy( kbpos, 3, root );
break;
+ case rt_KBXF:
+ rc = do_kbxf_copy( kbpos, 3, root );
+ break;
#ifdef HAVE_LIBGDBM
case rt_GDBM:
rc = do_gdbm_store( kbpos, root, 1 );
@@ -1544,6 +1589,478 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
}
+/****************************************************************
+ ********** Functions which operate on KBX files ****************
+ ****************************************************************/
+
+/****************
+ * search a KBX file return 0 if found, -1 if not found or an errorcode.
+ */
+static int
+do_kbxf_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
+{
+ 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);
+ kbpos->rt = rt_RING;
+ kbpos->valid = 0;
+
+ #if HAVE_DOSISH_SYSTEM || 1
+ assert(!iobuf);
+ iobuf = iobuf_open( fname );
+ if( !iobuf ) {
+ log_error("%s: can't open keyring file\n", fname);
+ rc = GPGERR_KEYRING_OPEN;
+ goto leave;
+ }
+ #else
+ if( iobuf_seek( iobuf, 0 ) ) {
+ log_error("can't rewind keyring file\n");
+ rc = GPGERR_KEYRING_OPEN;
+ goto leave;
+ }
+ #endif
+
+ 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( !rc ) {
+ kbpos->offset = offset;
+ kbpos->valid = 1;
+ }
+
+ leave:
+ free_packet(&pkt);
+ set_packet_list_mode(save_mode);
+ #if HAVE_DOSISH_SYSTEM || 1
+ iobuf_close(iobuf);
+ #endif
+ return rc;
+}
+
+
+static int
+do_kbxf_read( KBPOS *kbpos, KBNODE *ret_root )
+{
+ PACKET *pkt;
+ int rc;
+ RESTBL *rentry;
+ KBNODE root = NULL;
+ IOBUF a;
+ int in_cert = 0;
+
+ if( !(rentry=check_pos(kbpos)) )
+ return GPGERR_GENERAL;
+
+ a = iobuf_open( rentry->fname );
+ if( !a ) {
+ log_error("can't open `%s'\n", rentry->fname );
+ return GPGERR_OPEN_FILE;
+ }
+
+ if( !kbpos->valid )
+ log_debug("kbpos not valid in keyring_read, want %d\n", (int)kbpos->offset );
+ if( iobuf_seek( a, kbpos->offset ) ) {
+ log_error("can't seek to %lu\n", kbpos->offset);
+ iobuf_close(a);
+ return GPGERR_KEYRING_OPEN;
+ }
+
+ pkt = gcry_xmalloc( sizeof *pkt );
+ init_packet(pkt);
+ kbpos->count=0;
+ while( (rc=parse_packet(a, pkt)) != -1 ) {
+ if( rc ) { /* ignore errors */
+ if( rc != GPGERR_UNKNOWN_PACKET ) {
+ log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
+ rc = GPGERR_INV_KEYRING;
+ goto ready;
+ }
+ kbpos->count++;
+ free_packet( pkt );
+ init_packet( pkt );
+ continue;
+ }
+ /* make a linked list of all packets */
+ switch( pkt->pkttype ) {
+ case PKT_COMPRESSED:
+ log_error("skipped compressed packet in keyring\n" );
+ free_packet(pkt);
+ init_packet(pkt);
+ break;
+
+ 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 = gcry_xmalloc( sizeof *pkt );
+ init_packet(pkt);
+ break;
+ }
+ }
+ ready:
+ kbpos->valid = 0;
+ if( rc == -1 && root )
+ rc = 0;
+
+ if( rc )
+ release_kbnode( root );
+ else
+ *ret_root = root;
+ free_packet( pkt );
+ gcry_free( pkt );
+ iobuf_close(a);
+ return rc;
+}
+
+
+static int
+do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
+{
+ PACKET *pkt;
+ int rc;
+ RESTBL *rentry;
+ KBNODE root = NULL;
+
+ if( !(rentry=check_pos(kbpos)) )
+ return GPGERR_GENERAL;
+
+ if( kbpos->pkt ) {
+ root = new_kbnode( kbpos->pkt );
+ kbpos->pkt = NULL;
+ }
+
+ pkt = gcry_xmalloc( sizeof *pkt );
+ init_packet(pkt);
+ while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
+ if( rc ) { /* ignore errors */
+ if( rc != GPGERR_UNKNOWN_PACKET ) {
+ log_error("read_keyblock: read error: %s\n", gpg_errstr(rc) );
+ rc = GPGERR_INV_KEYRING;
+ goto ready;
+ }
+ free_packet( pkt );
+ init_packet( pkt );
+ continue;
+ }
+ /* make a linked list of all packets */
+ switch( pkt->pkttype ) {
+ case PKT_COMPRESSED:
+ log_error("skipped compressed packet in keyring\n" );
+ free_packet(pkt);
+ init_packet(pkt);
+ break;
+
+ 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 = gcry_xmalloc( 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 ) {
+ 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 = gcry_xmalloc( sizeof *pkt );
+ init_packet(pkt);
+ break;
+ }
+ }
+ ready:
+ if( rc == -1 && root )
+ rc = 0;
+
+ if( rc )
+ release_kbnode( root );
+ else
+ *ret_root = root;
+ free_packet( pkt );
+ gcry_free( pkt );
+
+ return rc;
+}
+
+
+/****************
+ * Perform insert/delete/update operation.
+ * mode 1 = insert
+ * 2 = delete
+ * 3 = update
+ */
+static int
+do_kbxf_copy( KBPOS *kbpos, int mode, KBNODE root )
+{
+ RESTBL *rentry;
+ IOBUF fp, newfp;
+ int rc=0;
+ char *bakfname = NULL;
+ char *tmpfname = NULL;
+
+ if( !(rentry = check_pos( kbpos )) )
+ return GPGERR_GENERAL;
+ if( kbpos->fp )
+ BUG(); /* not allowed with such a handle */
+
+ if( opt.dry_run )
+ return 0;
+
+ lock_rentry( rentry );
+
+ /* open the source file */
+ fp = iobuf_open( rentry->fname );
+ if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
+ KBNODE kbctx, node;
+
+ /* insert: create a new file */
+ newfp = iobuf_create( rentry->fname );
+ if( !newfp ) {
+ log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno));
+ unlock_rentry( rentry );
+ return GPGERR_OPEN_FILE;
+ }
+ else if( !opt.quiet )
+ log_info(_("%s: keyring created\n"), rentry->fname );
+
+ kbctx=NULL;
+ while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
+ if( (rc = build_packet( newfp, node->pkt )) ) {
+ log_error("build_packet(%d) failed: %s\n",
+ node->pkt->pkttype, gpg_errstr(rc) );
+ iobuf_cancel(newfp);
+ unlock_rentry( rentry );
+ return GPGERR_WRITE_FILE;
+ }
+ }
+ if( iobuf_close(newfp) ) {
+ log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
+ unlock_rentry( rentry );
+ return GPGERR_CLOSE_FILE;
+ }
+ if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
+ log_error("%s: chmod failed: %s\n",
+ rentry->fname, strerror(errno) );
+ unlock_rentry( rentry );
+ return GPGERR_WRITE_FILE;
+ }
+ return 0;
+ }
+ if( !fp ) {
+ log_error("%s: can't open: %s\n", rentry->fname, strerror(errno) );
+ rc = GPGERR_OPEN_FILE;
+ goto leave;
+ }
+
+ /* create the new file */
+ #ifdef USE_ONLY_8DOT3
+ /* Here is another Windoze bug?:
+ * you cant rename("pubring.gpg.tmp", "pubring.gpg");
+ * but rename("pubring.gpg.tmp", "pubring.aaa");
+ * works. So we replace .gpg by .bak or .tmp
+ */
+ if( strlen(rentry->fname) > 4
+ && !strcmp(rentry->fname+strlen(rentry->fname)-4, ".gpg") ) {
+ bakfname = gcry_xmalloc( strlen( rentry->fname ) + 1 );
+ strcpy(bakfname,rentry->fname);
+ strcpy(bakfname+strlen(rentry->fname)-4, ".bak");
+ tmpfname = gcry_xmalloc( strlen( rentry->fname ) + 1 );
+ strcpy(tmpfname,rentry->fname);
+ strcpy(tmpfname+strlen(rentry->fname)-4, ".tmp");
+ }
+ else { /* file does not end with gpg; hmmm */
+ bakfname = gcry_xmalloc( strlen( rentry->fname ) + 5 );
+ strcpy(stpcpy(bakfname,rentry->fname),".bak");
+ tmpfname = gcry_xmalloc( strlen( rentry->fname ) + 5 );
+ strcpy(stpcpy(tmpfname,rentry->fname),".tmp");
+ }
+ #else
+ bakfname = gcry_xmalloc( strlen( rentry->fname ) + 2 );
+ strcpy(stpcpy(bakfname,rentry->fname),"~");
+ tmpfname = gcry_xmalloc( strlen( rentry->fname ) + 5 );
+ strcpy(stpcpy(tmpfname,rentry->fname),".tmp");
+ #endif
+ newfp = iobuf_create( tmpfname );
+ if( !newfp ) {
+ log_error("%s: can't create: %s\n", tmpfname, strerror(errno) );
+ iobuf_close(fp);
+ rc = GPGERR_OPEN_FILE;
+ goto leave;
+ }
+
+ if( mode == 1 ) { /* insert */
+ /* copy everything to the new file */
+ rc = copy_all_packets( fp, newfp );
+ if( rc != -1 ) {
+ log_error("%s: copy to %s failed: %s\n",
+ rentry->fname, tmpfname, gpg_errstr(rc) );
+ iobuf_close(fp);
+ iobuf_cancel(newfp);
+ goto leave;
+ }
+ rc = 0;
+ }
+
+ if( mode == 2 || mode == 3 ) { /* delete or update */
+ /* copy first part to the new file */
+ rc = copy_some_packets( fp, newfp, kbpos->offset );
+ if( rc ) { /* should never get EOF here */
+ log_error("%s: copy to %s failed: %s\n",
+ rentry->fname, tmpfname, gpg_errstr(rc) );
+ iobuf_close(fp);
+ iobuf_cancel(newfp);
+ goto leave;
+ }
+ /* skip this keyblock */
+ assert( kbpos->count );
+ rc = skip_some_packets( fp, kbpos->count );
+ if( rc ) {
+ log_error("%s: skipping %u packets failed: %s\n",
+ rentry->fname, kbpos->count, gpg_errstr(rc));
+ iobuf_close(fp);
+ iobuf_cancel(newfp);
+ goto leave;
+ }
+ }
+
+ if( mode == 1 || mode == 3 ) { /* insert or update */
+ KBNODE kbctx, node;
+
+ /* append the new data */
+ kbctx=NULL;
+ while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
+ if( (rc = build_packet( newfp, node->pkt )) ) {
+ log_error("build_packet(%d) failed: %s\n",
+ node->pkt->pkttype, gpg_errstr(rc) );
+ iobuf_close(fp);
+ iobuf_cancel(newfp);
+ rc = GPGERR_WRITE_FILE;
+ goto leave;
+ }
+ }
+ kbpos->valid = 0;
+ }
+
+ if( mode == 2 || mode == 3 ) { /* delete or update */
+ /* copy the rest */
+ rc = copy_all_packets( fp, newfp );
+ if( rc != -1 ) {
+ log_error("%s: copy to %s failed: %s\n",
+ rentry->fname, tmpfname, gpg_errstr(rc) );
+ iobuf_close(fp);
+ iobuf_cancel(newfp);
+ goto leave;
+ }
+ rc = 0;
+ }
+
+ /* close both files */
+ if( iobuf_close(fp) ) {
+ log_error("%s: close failed: %s\n", rentry->fname, strerror(errno) );
+ rc = GPGERR_CLOSE_FILE;
+ goto leave;
+ }
+ if( iobuf_close(newfp) ) {
+ log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
+ rc = GPGERR_CLOSE_FILE;
+ goto leave;
+ }
+ /* if the new file is a secring, restrict the permissions */
+ #ifndef HAVE_DOSISH_SYSTEM
+ if( rentry->secret ) {
+ if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) {
+ log_error("%s: chmod failed: %s\n",
+ tmpfname, strerror(errno) );
+ rc = GPGERR_WRITE_FILE;
+ goto leave;
+ }
+ }
+ #endif
+
+ /* rename and make backup file */
+ if( !rentry->secret ) { /* but not for secret keyrings */
+ #ifdef HAVE_DOSISH_SYSTEM
+ remove( bakfname );
+ #endif
+ if( rename( rentry->fname, bakfname ) ) {
+ log_error("%s: rename to %s failed: %s\n",
+ rentry->fname, bakfname, strerror(errno) );
+ rc = GPGERR_RENAME_FILE;
+ goto leave;
+ }
+ }
+ #ifdef HAVE_DOSISH_SYSTEM
+ remove( rentry->fname );
+ #endif
+ if( rename( tmpfname, rentry->fname ) ) {
+ log_error("%s: rename to %s failed: %s\n",
+ tmpfname, rentry->fname,strerror(errno) );
+ rc = GPGERR_RENAME_FILE;
+ if( rentry->secret ) {
+ log_info(_(
+ "WARNING: 2 files with confidential information exists.\n"));
+ log_info(_("%s is the unchanged one\n"), rentry->fname );
+ log_info(_("%s is the new one\n"), tmpfname );
+ log_info(_("Please fix this possible security flaw\n"));
+ }
+ goto leave;
+ }
+
+ leave:
+ unlock_rentry( rentry );
+ gcry_free(bakfname);
+ gcry_free(tmpfname);
+ return rc;
+}
+
+
+
#ifdef HAVE_LIBGDBM
/****************************************************************
********** Functions which operates on GDM files ***************
diff --git a/scripts/db2html.in b/scripts/db2html.in
new file mode 100755
index 000000000..ba35afbc1
--- /dev/null
+++ b/scripts/db2html.in
@@ -0,0 +1,151 @@
+#!/bin/sh
+# db2html.in - Docbook to HTML rendering (wk 2000-02-15)
+#
+# Copyright (C) 2000 Free Software Foundation
+#
+# This 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.
+#
+# This 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
+
+nosplit=no
+copyfiles=no
+stylesheet=@DSL_FOR_HTML@
+JADE=@JADE@
+
+usage () {
+ echo 'usage: db2html [--nosplit] [--copyfiles] filename' >&2
+ exit 1
+}
+
+
+while test "`echo $1 | head -c1`" = "-"; do
+ case $1 in
+ --version)
+ cat <<EOF
+db2html 0.5
+Copyright (C) 2000 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+stylesteet: $stylesheet
+EOF
+ exit 0
+ ;;
+ --help|-h|-help)
+ usage
+ ;;
+ --nosplit)
+ nosplit=yes
+ ;;
+ --copyfiles)
+ copyfiles=yes
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "invalid option $1" >&2
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+if test $# = 1; then
+ input="$1"
+else
+ usage
+fi
+
+# grep the document type
+doctype=`grep -i '\<doctype' $input|awk 'NR==1 {print $2}'| tr '[A-Z]' '[a-z]'`
+if test -z $doctype; then
+ doctype=book
+ echo "no DOCTYPE found - assuming '$doctype'" >&2
+else
+ echo "DOCTYPE is '$doctype'" >&2
+fi
+
+output="`basename $input| sed 's/\.sgml$//'`.html"
+
+
+if test $nosplit = yes; then
+ echo "running jade on '$input' ..." >&2
+ $JADE -d $stylesheet -t sgml -i html -V nochunks $input > $output
+ echo "$output created"
+ exit 0
+fi
+
+if test -d html ; then
+ :
+else
+ if mkdir html; then
+ echo "'html' directory created" >&2
+ else
+ echo "failed to create 'html' directory" >&2
+ exit 1
+ fi
+fi
+
+outputdir="html/`basename $input| sed 's/\.sgml$//'`"
+
+if test -d $outputdir ; then
+ :
+else
+ if mkdir $outputdir; then
+ echo "'$outputdir' created" >&2
+ else
+ echo "failed to create '$outputdir'" >&2
+ exit 1
+ fi
+fi
+echo "creating html pages in '$outputdir' ..." >&2
+if test "$input" = "`basename $input`"; then
+ inp="../../$input"
+else
+ inp="$input"
+fi
+echo "running jade on '$inp' ..." >&2
+(cd $outputdir && $JADE -t sgml -i html -d $stylesheet $inp )
+echo "html version in '$outputdir' created" >&2
+
+# break out all filerefs and copy them to the outputdirectory
+# fixme: handling of path components is wrong
+if test $copyfiles = yes; then
+ echo "looking for filerefs ..." >&2
+ for file in `nsgmls -i html $input \
+ | awk '/^AFILEREF[ \t]+CDATA/ {print $3}'`; do
+ d=$outputdir/`basename $file`
+ if cat $file > $outputdir/`basename $file` ; then
+ echo " $file -> $d" >&2
+ fi
+ done
+fi
+
+mainfile=`ls $outputdir/${doctype}* | head -1`
+
+cat > $output <<EOF
+<html><title>$output</title>
+<body>
+
+<a href="$mainfile">$mainfile</a>
+
+</body>
+</html>
+EOF
+
+echo "$output created with link to '$mainfile'" >&2
+
+exit 0
+
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 92e008dfd..057f883e5 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -2,8 +2,10 @@
EXTRA_DIST = lspgpot
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
-needed_libs = ../gcrypt/libgcrypt.la \
- ../util/libutil.la ../jnlib/libjnlib.la @INTLLIBS@
+# we need to add libutil.la a second time because we have to resolve
+# gpg_log_ in some libjnlib modules. - very ugly - should be removed soon.
+needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la \
+ ../jnlib/libjnlib.la ../util/libutil.la @INTLLIBS@
noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest