summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/ChangeLog6
-rw-r--r--tools/Makefile.am23
-rw-r--r--tools/clean-sat.c34
-rwxr-xr-xtools/convert-from-10657
-rw-r--r--tools/crlf.c52
-rw-r--r--tools/gpg-zip.in142
-rw-r--r--tools/gpgsplit.c881
-rwxr-xr-xtools/lspgpot27
-rwxr-xr-xtools/mail-signed-keys114
-rw-r--r--tools/make-dns-cert.c239
-rw-r--r--tools/mk-tdata.c67
-rwxr-xr-xtools/pgpgroup-to-gpggroup42
12 files changed, 1680 insertions, 4 deletions
diff --git a/tools/ChangeLog b/tools/ChangeLog
index 25ffae5d2..af5925aa1 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,3 +1,9 @@
+2006-08-21 Werner Koch <wk@g10code.com>
+
+ * gpgsplit.c: New. Taken from 1.4. Adjusted to GnuPG2.
+
+ * Makefile.am (noinst_PROGRAMS): New.
+
2006-06-09 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (gpgconf_LDADD): Add $(GPG_ERROR_LIBS).
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 6b4767a79..702bd5187 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -18,8 +18,11 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
-EXTRA_DIST = Manifest watchgnupg.c \
- addgnupghome gpgsm-gencert.sh
+EXTRA_DIST = \
+ Manifest watchgnupg.c \
+ addgnupghome gpgsm-gencert.sh \
+ lspgpot mail-signed-keys convert-from-106
+
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common
include $(top_srcdir)/am/cmacros.am
@@ -29,6 +32,9 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
sbin_SCRIPTS = addgnupghome
bin_SCRIPTS = gpgsm-gencert.sh
+if HAVE_USTAR
+bin_SCRIPTS += gpg-zip
+endif
if BUILD_SYMCRYPTRUN
symcryptrun = symcryptrun
@@ -36,17 +42,24 @@ else
symcryptrun =
endif
-bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun} gpgparsemail
+bin_PROGRAMS = gpgconf gpg-connect-agent gpgkey2ssh ${symcryptrun} \
+ gpgparsemail gpgsplit
if !HAVE_W32_SYSTEM
bin_PROGRAMS += watchgnupg
endif
+noinst_PROGRAMS = clean-sat mk-tdata make-dns-cert
+
+common_libs = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a
+
+gpgsplit_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(ZLIBS)
+
gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c
# jnlib/common sucks in gpg-error, will they, nil they (some compilers
# do not eliminate the supposed-to-be-unused-inline-functions).
gpgconf_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \
- ../gl/libgnu.a @LIBINTL@ $(GPG_ERROR_LIBS)
+ ../gl/libgnu.a $(LIBINTL) $(GPG_ERROR_LIBS)
gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h
gpgparsemail_LDADD =
@@ -71,3 +84,5 @@ gpgkey2ssh_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
# some compilers do not eliminate.
gpgkey2ssh_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS)
+
+
diff --git a/tools/clean-sat.c b/tools/clean-sat.c
new file mode 100644
index 000000000..8b6bfd77a
--- /dev/null
+++ b/tools/clean-sat.c
@@ -0,0 +1,34 @@
+/* clean-sat.c
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+
+ if( argc > 1 ) {
+ fprintf(stderr, "no arguments, please\n");
+ return 1;
+ }
+
+ while( (c=getchar()) == '\n' )
+ ;
+ while( c != EOF ) {
+ putchar(c);
+ c = getchar();
+ }
+
+ return 0;
+}
+
diff --git a/tools/convert-from-106 b/tools/convert-from-106
new file mode 100755
index 000000000..634152b11
--- /dev/null
+++ b/tools/convert-from-106
@@ -0,0 +1,57 @@
+#!/bin/sh
+# Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+#
+# This program 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 program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+if ! gpg --version > /dev/null 2>&1 ; then
+ echo "GnuPG not available!"
+ exit 1
+fi
+
+gpg="gpg --no-greeting --no-secmem-warning"
+
+echo "This script converts your public keyring and trustdb from GnuPG"
+echo "1.0.6 or earlier to the 1.0.7 and later format."
+
+echo "If you have already done this, there is no harm (but no point)"
+echo "in doing it again."
+
+echo -n "Continue? (y/N)"
+
+read answer
+
+if test "x$answer" != "xy" ; then
+ exit 0
+fi
+
+echo
+echo "Marking your keys as ultimately trusted"
+for key in `$gpg --with-colons --list-secret-keys | grep sec: | cut -d: -f5`
+do
+ $gpg --trusted-key $key --with-colons --list-keys $key > /dev/null 2>&1
+ echo -n "."
+done
+echo
+
+echo
+echo "Adding signature caches"
+$gpg --rebuild-keydb-caches
+
+echo
+echo "Checking trustdb"
+$gpg --check-trustdb
+
+echo
+echo "Done!"
diff --git a/tools/crlf.c b/tools/crlf.c
new file mode 100644
index 000000000..ecb6eecdb
--- /dev/null
+++ b/tools/crlf.c
@@ -0,0 +1,52 @@
+/* crlf.c
+ * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ int c, lc;
+ int off=0;
+
+ if( argc > 1 ) {
+ fprintf(stderr, "no arguments, please\n");
+ return 1;
+ }
+
+ lc = -1;
+ while( (c=getchar()) != EOF ) {
+#if 0
+ if( c == '\r' && lc == ' ' )
+ fprintf(stderr,"SP,CR at %d\n", off );
+ if( c == '\n' && lc == ' ' )
+ fprintf(stderr,"SP,LF at %d\n", off );
+#endif
+ if( c == '\n' && lc == '\r' )
+ putchar(c);
+ else if( c == '\n' ) {
+ putchar('\r');
+ putchar(c);
+ }
+ else if( c != '\n' && lc == '\r' ) {
+ putchar('\n');
+ putchar(c);
+ }
+ else
+ putchar(c);
+
+ lc = c;
+ off++;
+ }
+
+ return 0;
+}
diff --git a/tools/gpg-zip.in b/tools/gpg-zip.in
new file mode 100644
index 000000000..8b4ccfb2b
--- /dev/null
+++ b/tools/gpg-zip.in
@@ -0,0 +1,142 @@
+#!/bin/sh
+
+# gpg-archive - gpg-ized tar using the same format as PGP's PGP Zip.
+# Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+# Despite the name, PGP Zip format is actually an OpenPGP-wrapped tar
+# file. To be compatible with PGP itself, this must be a USTAR format
+# tar file. Unclear on whether there is a distinction here between
+# the GNU or POSIX variant of USTAR.
+
+VERSION=@VERSION@
+TAR=@TAR@
+GPG=gpg
+
+usage="\
+Usage: gpg-zip [--help] [--version] [--encrypt] [--decrypt] [--symmetric]
+ [--list-archive] [--output FILE] [--gpg GPG] [--gpg-args ARGS]
+ [--tar TAR] [--tar-args ARGS] filename1 [filename2, ...]
+ directory1 [directory2, ...]
+
+Encrypt or sign files into an archive."
+
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*)
+ echo "$usage"
+ exit 0
+ ;;
+ --list-archive)
+ list=yes
+ create=no
+ unpack=no
+ shift
+ ;;
+ --encrypt | -e)
+ gpg_args="$gpg_args --encrypt"
+ list=no
+ create=yes
+ unpack=no
+ shift
+ ;;
+ --decrypt | -d)
+ gpg_args="$gpg_args --decrypt"
+ list=no
+ create=no
+ unpack=yes
+ shift
+ ;;
+ --symmetric | -c)
+ gpg_args="$gpg_args --symmetric"
+ list=no
+ create=yes
+ unpack=no
+ shift
+ ;;
+ --sign | -s)
+ gpg_args="$gpg_args --sign"
+ list=no
+ create=yes
+ unpack=no
+ shift
+ ;;
+ --recipient | -r)
+ gpg_args="$gpg_args --recipient $2"
+ shift
+ shift
+ ;;
+ --local-user | -u)
+ gpg_args="$gpg_args --local-user $2"
+ shift
+ shift
+ ;;
+ --output | -o)
+ gpg_args="$gpg_args --output $2"
+ shift
+ shift
+ ;;
+ --version)
+ echo "gpg-zip (GnuPG) $VERSION"
+ exit 0
+ ;;
+ --gpg)
+ GPG=$1
+ shift
+ ;;
+ --gpg-args)
+ gpg_args="$gpg_args $2"
+ shift
+ shift
+ ;;
+ --tar)
+ TAR=$1
+ shift
+ ;;
+ --tar-args)
+ tar_args="$tar_args $2"
+ shift
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+
+if test x$create = xyes ; then
+# echo "$TAR -cf - "$@" | $GPG --set-filename x.tar $gpg_args" 1>&2
+ $TAR -cf - "$@" | $GPG --set-filename x.tar $gpg_args
+elif test x$list = xyes ; then
+# echo "cat \"$1\" | $GPG $gpg_args | $TAR $tar_args -tf -" 1>&2
+ cat "$1" | $GPG $gpg_args | $TAR $tar_args -tf -
+elif test x$unpack = xyes ; then
+# echo "cat \"$1\" | $GPG $gpg_args | $TAR $tar_args -xvf -" 1>&2
+ cat "$1" | $GPG $gpg_args | $TAR $tar_args -xvf -
+else
+ echo "$usage" 1>&2
+ exit 1
+fi
diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c
new file mode 100644
index 000000000..96760dab3
--- /dev/null
+++ b/tools/gpgsplit.c
@@ -0,0 +1,881 @@
+/* gpgsplit.c - An OpenPGP packet splitting tool
+ * Copyright (C) 2001, 2002, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+/*
+ * TODO: Add an option to uncompress packets. This should come quite handy.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#ifdef HAVE_DOSISH_SYSTEM
+# include <fcntl.h> /* for setmode() */
+#endif
+#include <zlib.h>
+#ifdef HAVE_BZIP2
+#include <bzlib.h>
+#endif /* HAVE_BZIP2 */
+#if defined(__riscos__) && defined(USE_ZLIBRISCOS)
+# include "zlib-riscos.h"
+#endif
+
+#define INCLUDED_BY_MAIN_MODULE 1
+#include "util.h"
+#include "openpgpdefs.h"
+
+static int opt_verbose;
+static const char *opt_prefix = "";
+static int opt_uncompress;
+static int opt_secret_to_public;
+static int opt_no_split;
+
+static void g10_exit( int rc );
+static void split_packets (const char *fname);
+
+
+enum cmd_and_opt_values {
+ aNull = 0,
+ oVerbose = 'v',
+ oPrefix = 'p',
+ oUncompress = 500,
+ oSecretToPublic,
+ oNoSplit,
+
+ aTest
+};
+
+
+static ARGPARSE_OPTS opts[] = {
+
+ { 301, NULL, 0, "@Options:\n " },
+
+ { oVerbose, "verbose", 0, "verbose" },
+ { oPrefix, "prefix", 2, "|STRING|Prepend filenames with STRING" },
+ { oUncompress, "uncompress", 0, "uncompress a packet"},
+ { oSecretToPublic, "secret-to-public", 0, "convert secret keys to public keys"},
+ { oNoSplit, "no-split", 0, "write to stdout and don't actually split"},
+{0} };
+
+
+static const char *
+my_strusage (int level)
+{
+ const char *p;
+ switch (level)
+ {
+ case 11: p = "gpgsplit (GnuPG)";
+ break;
+ case 13: p = VERSION; break;
+ case 17: p = PRINTABLE_OS_NAME; break;
+ case 19: p =
+ "Please report bugs to <bug-gnupg@gnu.org>.\n";
+ break;
+ case 1:
+ case 40: p =
+ "Usage: gpgsplit [options] [files] (-h for help)";
+ break;
+ case 41: p =
+ "Syntax: gpgsplit [options] [files]\n"
+ "Split an OpenPGP message into packets\n";
+ break;
+
+ default: p = NULL;
+ }
+ return p;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ ARGPARSE_ARGS pargs;
+
+#ifdef HAVE_DOSISH_SYSTEM
+ setmode( fileno(stdin), O_BINARY );
+ setmode( fileno(stdout), O_BINARY );
+#endif
+ log_set_prefix ("gpgsplit", JNLIB_LOG_WITH_PREFIX);
+ set_strusage (my_strusage);
+
+ pargs.argc = &argc;
+ pargs.argv = &argv;
+ pargs.flags= 1; /* do not remove the args */
+ while (optfile_parse( NULL, NULL, NULL, &pargs, opts))
+ {
+ switch (pargs.r_opt)
+ {
+ case oVerbose: opt_verbose = 1; break;
+ case oPrefix: opt_prefix = pargs.r.ret_str; break;
+ case oUncompress: opt_uncompress = 1; break;
+ case oSecretToPublic: opt_secret_to_public = 1; break;
+ case oNoSplit: opt_no_split = 1; break;
+ default : pargs.err = 2; break;
+ }
+ }
+
+ if (log_get_errorcount(0))
+ g10_exit (2);
+
+ if (!argc)
+ split_packets (NULL);
+ else
+ {
+ for ( ;argc; argc--, argv++)
+ split_packets (*argv);
+ }
+
+ g10_exit (0);
+ return 0;
+}
+
+
+static void
+g10_exit (int rc)
+{
+ rc = rc? rc : log_get_errorcount(0)? 2 : 0;
+ exit(rc );
+}
+
+static const char *
+pkttype_to_string (int pkttype)
+{
+ const char *s;
+
+ switch (pkttype)
+ {
+ case PKT_PUBKEY_ENC : s = "pk_enc"; break;
+ case PKT_SIGNATURE : s = "sig"; break;
+ case PKT_SYMKEY_ENC : s = "sym_enc"; break;
+ case PKT_ONEPASS_SIG : s = "onepass_sig"; break;
+ case PKT_SECRET_KEY : s = "secret_key"; break;
+ case PKT_PUBLIC_KEY : s = "public_key"; break;
+ case PKT_SECRET_SUBKEY : s = "secret_subkey"; break;
+ case PKT_COMPRESSED :
+ s = opt_uncompress? "uncompressed":"compressed";
+ break;
+ case PKT_ENCRYPTED : s = "encrypted"; break;
+ case PKT_MARKER : s = "marker"; break;
+ case PKT_PLAINTEXT : s = "plaintext"; break;
+ case PKT_RING_TRUST : s = "ring_trust"; break;
+ case PKT_USER_ID : s = "user_id"; break;
+ case PKT_PUBLIC_SUBKEY : s = "public_subkey"; break;
+ case PKT_OLD_COMMENT : s = "old_comment"; break;
+ case PKT_ATTRIBUTE : s = "attribute"; break;
+ case PKT_ENCRYPTED_MDC : s = "encrypted_mdc"; break;
+ case PKT_MDC : s = "mdc"; break;
+ case PKT_COMMENT : s = "comment"; break;
+ case PKT_GPG_CONTROL : s = "gpg_control"; break;
+ default: s = "unknown"; break;
+ }
+ return s;
+}
+
+
+/*
+ * Create a new filename and a return a pointer to a statically
+ * allocated buffer
+ */
+static char *
+create_filename (int pkttype)
+{
+ static unsigned int partno = 0;
+ static char *name;
+
+ if (!name)
+ name = xmalloc (strlen (opt_prefix) + 100 );
+
+ assert (pkttype < 1000 && pkttype >= 0 );
+ partno++;
+ sprintf (name, "%s%06u-%03d" EXTSEP_S "%.40s",
+ opt_prefix, partno, pkttype, pkttype_to_string (pkttype));
+ return name;
+}
+
+static int
+read_u16 (FILE *fp, size_t *rn)
+{
+ int c;
+
+ if ( (c = getc (fp)) == EOF )
+ return -1;
+ *rn = c << 8;
+ if ( (c = getc (fp)) == EOF )
+ return -1;
+ *rn |= c;
+ return 0;
+}
+
+static int
+read_u32 (FILE *fp, unsigned long *rn)
+{
+ size_t tmp;
+
+ if (read_u16 (fp, &tmp))
+ return -1;
+ *rn = tmp << 16;
+ if (read_u16 (fp, &tmp))
+ return -1;
+ *rn |= tmp;
+ return 0;
+}
+
+static int
+write_old_header (FILE *fp, int pkttype, unsigned int len)
+{
+ int ctb = (0x80 | ((pkttype & 15)<<2));
+
+ if (len < 256)
+ ;
+ else if (len < 65536)
+ ctb |= 1;
+ else
+ ctb |= 2;
+
+ if ( putc ( ctb, fp) == EOF )
+ return -1;
+
+ if ( (ctb & 2) )
+ {
+ if (putc ((len>>24), fp) == EOF)
+ return -1;
+ if (putc ((len>>16), fp) == EOF)
+ return -1;
+ }
+ if ( (ctb & 3) )
+ {
+ if (putc ((len>>8), fp) == EOF)
+ return -1;
+ }
+ if (putc ((len&0xff), fp) == EOF)
+ return -1;
+ return 0;
+}
+
+static int
+write_new_header (FILE *fp, int pkttype, unsigned int len)
+{
+ if ( putc ((0xc0 | (pkttype & 0x3f)), fp) == EOF )
+ return -1;
+
+ if (len < 192)
+ {
+ if (putc (len, fp) == EOF)
+ return -1;
+ }
+ else if (len < 8384)
+ {
+ len -= 192;
+ if (putc ((len/256)+192, fp) == EOF)
+ return -1;
+ if (putc ((len%256), fp) == EOF)
+ return -1;
+ }
+ else
+ {
+ if (putc ( 0xff, fp) == EOF)
+ return -1;
+ if (putc ( (len >> 24), fp) == EOF)
+ return -1;
+ if (putc ( (len >> 16), fp) == EOF)
+ return -1;
+ if (putc ( (len >> 8), fp) == EOF)
+ return -1;
+ if (putc ( (len & 0xff), fp) == EOF)
+ return -1;
+ }
+ return 0;
+}
+
+/* Return the length of the public key given BUF of BUFLEN with a
+ secret key. */
+static int
+public_key_length (const unsigned char *buf, size_t buflen)
+{
+ const unsigned char *s;
+ int nmpis;
+
+ /* byte version number (3 or 4)
+ u32 creation time
+ [u16 valid days (version 3 only)]
+ byte algorithm
+ n MPIs (n and e) */
+ if (!buflen)
+ return 0;
+ if (buf[0] < 2 || buf[0] > 4)
+ return 0; /* wrong version number */
+ if (buflen < (buf[0] == 4? 6:8))
+ return 0;
+ s = buf + (buf[0] == 4? 6:8);
+ buflen -= (buf[0] == 4? 6:8);
+ switch (s[-1])
+ {
+ case 1:
+ case 2:
+ case 3:
+ nmpis = 2;
+ break;
+ case 16:
+ case 20:
+ nmpis = 3;
+ break;
+ case 17:
+ nmpis = 4;
+ break;
+ default:
+ return 0;
+ }
+
+ for (; nmpis; nmpis--)
+ {
+ unsigned int nbits, nbytes;
+
+ if (buflen < 2)
+ return 0;
+ nbits = (s[0] << 8) | s[1];
+ s += 2; buflen -= 2;
+ nbytes = (nbits+7) / 8;
+ if (buflen < nbytes)
+ return 0;
+ s += nbytes; buflen -= nbytes;
+ }
+
+ return s - buf;
+}
+
+static int
+handle_zlib(int algo,FILE *fpin,FILE *fpout)
+{
+ z_stream zs;
+ byte *inbuf, *outbuf;
+ unsigned int inbufsize, outbufsize;
+ int c,zinit_done, zrc, nread, count;
+ size_t n;
+
+ memset (&zs, 0, sizeof zs);
+ inbufsize = 2048;
+ inbuf = xmalloc (inbufsize);
+ outbufsize = 8192;
+ outbuf = xmalloc (outbufsize);
+ zs.avail_in = 0;
+ zinit_done = 0;
+
+ do
+ {
+ if (zs.avail_in < inbufsize)
+ {
+ n = zs.avail_in;
+ if (!n)
+ zs.next_in = (Bytef *) inbuf;
+ count = inbufsize - n;
+ for (nread=0;
+ nread < count && (c=getc (fpin)) != EOF;
+ nread++)
+ inbuf[n+nread] = c;
+
+ n += nread;
+ if (nread < count && algo == 1)
+ {
+ inbuf[n] = 0xFF; /* chew dummy byte */
+ n++;
+ }
+ zs.avail_in = n;
+ }
+ zs.next_out = (Bytef *) outbuf;
+ zs.avail_out = outbufsize;
+
+ if (!zinit_done)
+ {
+ zrc = (algo == 1? inflateInit2 ( &zs, -13)
+ : inflateInit ( &zs ));
+ if (zrc != Z_OK)
+ {
+ log_fatal ("zlib problem: %s\n", zs.msg? zs.msg :
+ zrc == Z_MEM_ERROR ? "out of core" :
+ zrc == Z_VERSION_ERROR ?
+ "invalid lib version" :
+ "unknown error" );
+ }
+ zinit_done = 1;
+ }
+ else
+ {
+#ifdef Z_SYNC_FLUSH
+ zrc = inflate (&zs, Z_SYNC_FLUSH);
+#else
+ zrc = inflate (&zs, Z_PARTIAL_FLUSH);
+#endif
+ if (zrc == Z_STREAM_END)
+ ; /* eof */
+ else if (zrc != Z_OK && zrc != Z_BUF_ERROR)
+ {
+ if (zs.msg)
+ log_fatal ("zlib inflate problem: %s\n", zs.msg );
+ else
+ log_fatal ("zlib inflate problem: rc=%d\n", zrc );
+ }
+ for (n=0; n < outbufsize - zs.avail_out; n++)
+ {
+ if (putc (outbuf[n], fpout) == EOF )
+ return 1;
+ }
+ }
+ }
+ while (zrc != Z_STREAM_END && zrc != Z_BUF_ERROR);
+ inflateEnd (&zs);
+
+ return 0;
+}
+
+#ifdef HAVE_BZIP2
+static int
+handle_bzip2(int algo,FILE *fpin,FILE *fpout)
+{
+ bz_stream bzs;
+ byte *inbuf, *outbuf;
+ unsigned int inbufsize, outbufsize;
+ int c,zinit_done, zrc, nread, count;
+ size_t n;
+
+ memset (&bzs, 0, sizeof bzs);
+ inbufsize = 2048;
+ inbuf = xmalloc (inbufsize);
+ outbufsize = 8192;
+ outbuf = xmalloc (outbufsize);
+ bzs.avail_in = 0;
+ zinit_done = 0;
+
+ do
+ {
+ if (bzs.avail_in < inbufsize)
+ {
+ n = bzs.avail_in;
+ if (!n)
+ bzs.next_in = inbuf;
+ count = inbufsize - n;
+ for (nread=0;
+ nread < count && (c=getc (fpin)) != EOF;
+ nread++)
+ inbuf[n+nread] = c;
+
+ n += nread;
+ if (nread < count && algo == 1)
+ {
+ inbuf[n] = 0xFF; /* chew dummy byte */
+ n++;
+ }
+ bzs.avail_in = n;
+ }
+ bzs.next_out = outbuf;
+ bzs.avail_out = outbufsize;
+
+ if (!zinit_done)
+ {
+ zrc = BZ2_bzDecompressInit(&bzs,0,0);
+ if (zrc != BZ_OK)
+ log_fatal ("bz2lib problem: %d\n",zrc);
+ zinit_done = 1;
+ }
+ else
+ {
+ zrc = BZ2_bzDecompress(&bzs);
+ if (zrc == BZ_STREAM_END)
+ ; /* eof */
+ else if (zrc != BZ_OK && zrc != BZ_PARAM_ERROR)
+ log_fatal ("bz2lib inflate problem: %d\n", zrc );
+ for (n=0; n < outbufsize - bzs.avail_out; n++)
+ {
+ if (putc (outbuf[n], fpout) == EOF )
+ return 1;
+ }
+ }
+ }
+ while (zrc != BZ_STREAM_END && zrc != BZ_PARAM_ERROR);
+ BZ2_bzDecompressEnd(&bzs);
+
+ return 0;
+}
+#endif /* HAVE_BZIP2 */
+
+/* hdr must point to a buffer large enough to hold all header bytes */
+static int
+write_part ( const char *fname, FILE *fpin, unsigned long pktlen,
+ int pkttype, int partial, unsigned char *hdr, size_t hdrlen)
+{
+ FILE *fpout;
+ int c, first;
+ unsigned char *p;
+ const char *outname = create_filename (pkttype);
+
+#if defined(__riscos__) && defined(USE_ZLIBRISCOS)
+ static int initialized = 0;
+
+ if (!initialized)
+ initialized = riscos_load_module("ZLib", zlib_path, 1);
+#endif
+ if (opt_no_split)
+ fpout = stdout;
+ else
+ {
+ if (opt_verbose)
+ log_info ("writing `%s'\n", outname);
+ fpout = fopen (outname, "wb");
+ if (!fpout)
+ {
+ log_error ("error creating `%s': %s\n", outname, strerror(errno));
+ /* stop right now, otherwise we would mess up the sequence
+ of the part numbers */
+ g10_exit (1);
+ }
+ }
+
+ if (opt_secret_to_public
+ && (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY))
+ {
+ unsigned char *blob = xmalloc (pktlen);
+ int i, len;
+
+ pkttype = pkttype == PKT_SECRET_KEY? PKT_PUBLIC_KEY:PKT_PUBLIC_SUBKEY;
+
+ for (i=0; i < pktlen; i++)
+ {
+ c = getc (fpin);
+ if (c == EOF)
+ goto read_error;
+ blob[i] = c;
+ }
+ len = public_key_length (blob, pktlen);
+ if (!len)
+ {
+ log_error ("error calcualting public key length\n");
+ g10_exit (1);
+ }
+ if ( (hdr[0] & 0x40) )
+ {
+ if (write_new_header (fpout, pkttype, len))
+ goto write_error;
+ }
+ else
+ {
+ if (write_old_header (fpout, pkttype, len))
+ goto write_error;
+ }
+
+ for (i=0; i < len; i++)
+ {
+ if ( putc (blob[i], fpout) == EOF )
+ goto write_error;
+ }
+
+ goto ready;
+ }
+
+
+ if (!opt_uncompress)
+ {
+ for (p=hdr; hdrlen; p++, hdrlen--)
+ {
+ if ( putc (*p, fpout) == EOF )
+ goto write_error;
+ }
+ }
+
+ first = 1;
+ while (partial)
+ {
+ size_t partlen;
+
+ if (partial == 1)
+ { /* openpgp */
+ if (first )
+ {
+ c = pktlen;
+ assert( c >= 224 && c < 255 );
+ first = 0;
+ }
+ else if ((c = getc (fpin)) == EOF )
+ goto read_error;
+ else
+ hdr[hdrlen++] = c;
+
+ if (c < 192)
+ {
+ pktlen = c;
+ partial = 0; /* (last segment may follow) */
+ }
+ else if (c < 224 )
+ {
+ pktlen = (c - 192) * 256;
+ if ((c = getc (fpin)) == EOF)
+ goto read_error;
+ hdr[hdrlen++] = c;
+ pktlen += c + 192;
+ partial = 0;
+ }
+ else if (c == 255)
+ {
+ if (read_u32 (fpin, &pktlen))
+ goto read_error;
+ hdr[hdrlen++] = pktlen >> 24;
+ hdr[hdrlen++] = pktlen >> 16;
+ hdr[hdrlen++] = pktlen >> 8;
+ hdr[hdrlen++] = pktlen;
+ partial = 0;
+ }
+ else
+ { /* next partial body length */
+ for (p=hdr; hdrlen; p++, hdrlen--)
+ {
+ if ( putc (*p, fpout) == EOF )
+ goto write_error;
+ }
+ partlen = 1 << (c & 0x1f);
+ for (; partlen; partlen--)
+ {
+ if ((c = getc (fpin)) == EOF)
+ goto read_error;
+ if ( putc (c, fpout) == EOF )
+ goto write_error;
+ }
+ }
+ }
+ else if (partial == 2)
+ { /* old gnupg */
+ assert (!pktlen);
+ if ( read_u16 (fpin, &partlen) )
+ goto read_error;
+ hdr[hdrlen++] = partlen >> 8;
+ hdr[hdrlen++] = partlen;
+ for (p=hdr; hdrlen; p++, hdrlen--)
+ {
+ if ( putc (*p, fpout) == EOF )
+ goto write_error;
+ }
+ if (!partlen)
+ partial = 0; /* end of packet */
+ for (; partlen; partlen--)
+ {
+ c = getc (fpin);
+ if (c == EOF)
+ goto read_error;
+ if ( putc (c, fpout) == EOF )
+ goto write_error;
+ }
+ }
+ else
+ { /* compressed: read to end */
+ pktlen = 0;
+ partial = 0;
+ hdrlen = 0;
+ if (opt_uncompress)
+ {
+ if ((c = getc (fpin)) == EOF)
+ goto read_error;
+
+ if(c==1 || c==2)
+ {
+ if(handle_zlib(c,fpin,fpout))
+ goto write_error;
+ }
+#ifdef HAVE_BZIP2
+ else if(c==3)
+ {
+ if(handle_bzip2(c,fpin,fpout))
+ goto write_error;
+ }
+#endif /* HAVE_BZIP2 */
+ else
+ {
+ log_error("invalid compression algorithm (%d)\n",c);
+ goto read_error;
+ }
+ }
+ else
+ {
+ while ( (c=getc (fpin)) != EOF )
+ {
+ if ( putc (c, fpout) == EOF )
+ goto write_error;
+ }
+ }
+ if (!feof (fpin))
+ goto read_error;
+ }
+ }
+
+ for (p=hdr; hdrlen; p++, hdrlen--)
+ {
+ if ( putc (*p, fpout) == EOF )
+ goto write_error;
+ }
+
+ /* standard packet or last segment of partial length encoded packet */
+ for (; pktlen; pktlen--)
+ {
+ c = getc (fpin);
+ if (c == EOF)
+ goto read_error;
+ if ( putc (c, fpout) == EOF )
+ goto write_error;
+ }
+
+ ready:
+ if ( !opt_no_split && fclose (fpout) )
+ log_error ("error closing `%s': %s\n", outname, strerror (errno));
+ return 0;
+
+ write_error:
+ log_error ("error writing `%s': %s\n", outname, strerror (errno));
+ if (!opt_no_split)
+ fclose (fpout);
+ return 2;
+
+ read_error:
+ if (!opt_no_split)
+ {
+ int save = errno;
+ fclose (fpout);
+ errno = save;
+ }
+ return -1;
+}
+
+
+
+static int
+do_split (const char *fname, FILE *fp)
+{
+ int c, ctb, pkttype;
+ unsigned long pktlen = 0;
+ int partial = 0;
+ unsigned char header[20];
+ int header_idx = 0;
+
+ ctb = getc (fp);
+ if (ctb == EOF)
+ return 3; /* ready */
+ header[header_idx++] = ctb;
+
+ if (!(ctb & 0x80))
+ {
+ log_error("invalid CTB %02x\n", ctb );
+ return 1;
+ }
+ if ( (ctb & 0x40) )
+ { /* new CTB */
+ pkttype = (ctb & 0x3f);
+ if( (c = getc (fp)) == EOF )
+ return -1;
+ header[header_idx++] = c;
+
+ if ( c < 192 )
+ pktlen = c;
+ else if ( c < 224 )
+ {
+ pktlen = (c - 192) * 256;
+ if( (c = getc (fp)) == EOF )
+ return -1;
+ header[header_idx++] = c;
+ pktlen += c + 192;
+ }
+ else if ( c == 255 )
+ {
+ if (read_u32 (fp, &pktlen))
+ return -1;
+ header[header_idx++] = pktlen >> 24;
+ header[header_idx++] = pktlen >> 16;
+ header[header_idx++] = pktlen >> 8;
+ header[header_idx++] = pktlen;
+ }
+ else
+ { /* partial body length */
+ pktlen = c;
+ partial = 1;
+ }
+ }
+ else
+ {
+ int lenbytes;
+
+ pkttype = (ctb>>2)&0xf;
+ lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
+ if (!lenbytes )
+ {
+ pktlen = 0; /* don't know the value */
+ if( pkttype == PKT_COMPRESSED )
+ partial = 3;
+ else
+ partial = 2; /* the old GnuPG partial length encoding */
+ }
+ else
+ {
+ for ( ; lenbytes; lenbytes-- )
+ {
+ pktlen <<= 8;
+ if( (c = getc (fp)) == EOF )
+ return -1;
+ header[header_idx++] = c;
+
+ pktlen |= c;
+ }
+ }
+ }
+
+ return write_part (fname, fp, pktlen, pkttype, partial,
+ header, header_idx);
+}
+
+
+static void
+split_packets (const char *fname)
+{
+ FILE *fp;
+ int rc;
+
+ if (!fname || !strcmp (fname, "-"))
+ {
+ fp = stdin;
+ fname = "-";
+ }
+ else if ( !(fp = fopen (fname,"rb")) )
+ {
+ log_error ("can't open `%s': %s\n", fname, strerror (errno));
+ return;
+ }
+
+ while ( !(rc = do_split (fname, fp)) )
+ ;
+ if ( rc > 0 )
+ ; /* error already handled */
+ else if ( ferror (fp) )
+ log_error ("error reading `%s': %s\n", fname, strerror (errno));
+ else
+ log_error ("premature EOF while reading `%s'\n", fname );
+
+ if ( fp != stdin )
+ fclose (fp);
+}
diff --git a/tools/lspgpot b/tools/lspgpot
new file mode 100755
index 000000000..f406392eb
--- /dev/null
+++ b/tools/lspgpot
@@ -0,0 +1,27 @@
+#!/bin/sh
+# lspgpot - script to extract the ownertrust values
+# from PGP keyrings and list them in GnuPG ownertrust format.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+if ! gpg --version > /dev/null 2>&1 ; then
+ echo "GnuPG not available!"
+ exit 1
+fi
+
+gpg --dry-run --with-fingerprint --with-colons $* | awk '
+BEGIN { FS=":"
+ printf "# Ownertrust listing generated by lspgpot\n"
+ printf "# This can be imported using the command:\n"
+ printf "# gpg --import-ownertrust\n\n" }
+$1 == "fpr" { fpr = $10 }
+$1 == "rtv" && $2 == 1 && $3 == 2 { printf "%s:3:\n", fpr; next }
+$1 == "rtv" && $2 == 1 && $3 == 5 { printf "%s:4:\n", fpr; next }
+$1 == "rtv" && $2 == 1 && $3 == 6 { printf "%s:5:\n", fpr; next }
+'
diff --git a/tools/mail-signed-keys b/tools/mail-signed-keys
new file mode 100755
index 000000000..80fbb3481
--- /dev/null
+++ b/tools/mail-signed-keys
@@ -0,0 +1,114 @@
+#!/bin/sh
+# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# FIXME: Add --dry-run, use only valid email addreses, extract only given keys
+
+dryrun=0
+if [ "$1" = "--dry-run" ]; then
+ dryrun=1
+ shift
+fi
+
+if [ -z "$1" -o -z "$2" -o -z "$3" ]; then
+ echo "usage: mail-signed-keys keyring signedby signame" >&2
+ exit 1
+fi
+
+signame="$3"
+
+if [ ! -f $1 ]; then
+ echo "mail-signed-keys: '$1': no such file" >&2
+ exit 1
+fi
+
+[ -f '.#tdb.tmp' ] && rm '.#tdb.tmp'
+ro="--homedir . --no-options --trustdb-name=./.#tdb.tmp --dry-run --lock-never --no-default-keyring --keyring $1"
+
+signedby=`gpg $ro --list-keys --with-colons $2 \
+ 2>/dev/null | awk -F: '$1=="pub" {print $5; exit 0}'`
+
+if [ -z "$signedby" ]; then
+ echo "mail-signed-keys: '$2': no such signator" >&2
+ exit 1
+fi
+
+if [ "$dryrun" = "0" ]; then
+ echo "About to send the the keys signed by $signedby" >&2
+ echo -n "to their owners. Do you really want to do this? (y/N)" >&2
+ read
+ [ "$REPLY" != "y" -a "$REPLY" != "Y" ] && exit 0
+fi
+
+gpg $ro --check-sigs --with-colons 2>/dev/null \
+ | awk -F: -v signedby="$signedby" -v gpgopt="$ro" \
+ -v dryrun="$dryrun" -v signame="$signame" '
+BEGIN { sendmail="/usr/lib/sendmail -oi -t " }
+$1 == "pub" { nextkid=$5; nextuid=$10
+ if( uidcount > 0 ) { myflush() }
+ kid=nextkid; uid=nextuid; next
+ }
+$1 == "uid" { uid=$10 ; next }
+$1 == "sig" && $2 == "!" && $5 == signedby { uids[uidcount++] = uid; next }
+END { if( uidcount > 0 ) { myflush() } }
+
+function myflush()
+{
+ if ( kid == signedby ) { uidcount=0; return }
+ print "sending key " substr(kid,9) " to" | "cat >&2"
+ for(i=0; i < 1; i++ ) {
+ print " " uids[i] | "cat >&2"
+ if( dryrun == 0 ) {
+ if( i == 0 ) {
+ printf "To: %s", uids[i] | sendmail
+ }
+ else {
+ printf ",\n %s", uids[i] | sendmail
+ }
+ }
+ }
+ if(dryrun == 0) {
+ printf "\n" | sendmail
+ print "Subject: I signed your key " substr(kid,9) | sendmail
+ print "" | sendmail
+ print "Hi," | sendmail
+ print "" | sendmail
+ print "Here you get back the signed key." | sendmail
+ print "Please send it yourself to a keyserver." | sendmail
+ print "" | sendmail
+ print "Peace," | sendmail
+ print " " signame | sendmail
+ print "" | sendmail
+ cmd = "gpg " gpgopt " --export -a " kid " 2>/dev/null"
+ while( (cmd | getline) > 0 ) {
+ print | sendmail
+ }
+ print "" | sendmail
+ close(cmd)
+ close( sendmail )
+ }
+ uidcount=0
+}
+'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/make-dns-cert.c b/tools/make-dns-cert.c
new file mode 100644
index 000000000..496b63b0b
--- /dev/null
+++ b/tools/make-dns-cert.c
@@ -0,0 +1,239 @@
+/* make-dns-cert.c - An OpenPGP-to-DNS CERT conversion tool
+ * Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <config.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* We use TYPE37 instead of CERT since not all nameservers can handle
+ CERT yet... */
+
+static int
+cert_key(const char *name,const char *keyfile)
+{
+ int fd,ret=1,err,i;
+ struct stat statbuf;
+
+ fd=open(keyfile,O_RDONLY);
+ if(fd==-1)
+ {
+ fprintf(stderr,"Cannot open key file %s: %s\n",keyfile,strerror(errno));
+ return 1;
+ }
+
+ err=fstat(fd,&statbuf);
+ if(err==-1)
+ {
+ fprintf(stderr,"Unable to stat key file %s: %s\n",
+ keyfile,strerror(errno));
+ goto fail;
+ }
+
+ if(statbuf.st_size>65536)
+ {
+ fprintf(stderr,"Key %s too large for CERT encoding\n",keyfile);
+ goto fail;
+ }
+
+ if(statbuf.st_size>16384)
+ fprintf(stderr,"Warning: key file %s is larger than the default"
+ " GnuPG max-cert-size\n",keyfile);
+
+ printf("%s\tTYPE37\t\\# %u 0003 0000 00 ",
+ name,(unsigned int)statbuf.st_size+5);
+
+ err=1;
+ while(err!=0)
+ {
+ unsigned char buffer[1024];
+
+ err=read(fd,buffer,1024);
+ if(err==-1)
+ {
+ fprintf(stderr,"Unable to read key file %s: %s\n",
+ keyfile,strerror(errno));
+ goto fail;
+ }
+
+ for(i=0;i<err;i++)
+ printf("%02X",buffer[i]);
+ }
+
+ printf("\n");
+
+ ret=0;
+
+ fail:
+ close(fd);
+
+ return ret;
+}
+
+static int
+url_key(const char *name,const char *fpr,const char *url)
+{
+ int len=6,fprlen=0;
+
+ if(fpr)
+ {
+ const char *tmp = fpr;
+ while (*tmp)
+ {
+ if ((*tmp >= 'A' && *tmp <= 'F') ||
+ (*tmp >= 'a' && *tmp <= 'f') ||
+ (*tmp >= '0' && *tmp <= '9'))
+ {
+ fprlen++;
+ }
+ else if (*tmp != ' ' && *tmp != '\t')
+ {
+ fprintf(stderr,"Fingerprint must consist of only hex digits"
+ " and whitespace\n");
+ return 1;
+ }
+
+ tmp++;
+ }
+
+ if(fprlen%2)
+ {
+ fprintf(stderr,"Fingerprint must be an even number of characters\n");
+ return 1;
+ }
+
+ fprlen/=2;
+ len+=fprlen;
+ }
+
+ if(url)
+ len+=strlen(url);
+
+ if(!fpr && !url)
+ {
+ fprintf(stderr,
+ "Cannot generate a CERT without either a fingerprint or URL\n");
+ return 1;
+ }
+
+ printf("%s\tTYPE37\t\\# %d 0006 0000 00 %02X",name,len,fprlen);
+
+ if(fpr)
+ printf(" %s",fpr);
+
+ if(url)
+ {
+ const char *c;
+ printf(" ");
+ for(c=url;*c;c++)
+ printf("%02X",*c);
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+static void
+usage(FILE *stream)
+{
+ fprintf(stream,"make-dns-cert\n");
+ fprintf(stream,"\t-f\tfingerprint\n");
+ fprintf(stream,"\t-u\tURL\n");
+ fprintf(stream,"\t-k\tkey file\n");
+ fprintf(stream,"\t-n\tDNS name\n");
+}
+
+int
+main(int argc,char *argv[])
+{
+ int arg,err=1;
+ char *fpr=NULL,*url=NULL,*keyfile=NULL,*name=NULL;
+
+ if(argc==1)
+ {
+ usage(stderr);
+ return 1;
+ }
+ else if(argc>1 && strcmp(argv[1],"--version")==0)
+ {
+ printf("make-dns-cert (GnuPG) " VERSION "\n");
+ return 0;
+ }
+ else if(argc>1 && strcmp(argv[1],"--help")==0)
+ {
+ usage(stdout);
+ return 0;
+ }
+
+ while((arg=getopt(argc,argv,"hf:u:k:n:"))!=-1)
+ switch(arg)
+ {
+ default:
+ case 'h':
+ usage(stdout);
+ exit(0);
+
+ case 'f':
+ fpr=optarg;
+ break;
+
+ case 'u':
+ url=optarg;
+ break;
+
+ case 'k':
+ keyfile=optarg;
+ break;
+
+ case 'n':
+ name=optarg;
+ break;
+ }
+
+ if(!name)
+ {
+ fprintf(stderr,"No name provided\n");
+ return 1;
+ }
+
+ if(keyfile && (fpr || url))
+ {
+ fprintf(stderr,"Cannot generate a CERT record with both a keyfile and"
+ " a fingerprint or URL\n");
+ return 1;
+ }
+
+ if(keyfile)
+ err=cert_key(name,keyfile);
+ else
+ err=url_key(name,fpr,url);
+
+ return err;
+}
diff --git a/tools/mk-tdata.c b/tools/mk-tdata.c
new file mode 100644
index 000000000..833875d28
--- /dev/null
+++ b/tools/mk-tdata.c
@@ -0,0 +1,67 @@
+/* mk-tdata.c - Create some simple random testdata
+ * Copyright (C) 1998, 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#ifndef RAND_MAX /* for SunOS */
+#define RAND_MAX 32767
+#endif
+
+int
+main(int argc, char **argv)
+{
+ int i, c = 0;
+ int limit =0;
+ int char_mode = 0;
+
+ if (argc)
+ {
+ argc--;
+ argv++;
+ }
+
+ /* Check for option --char N */
+ if (argc > 1 && !strcmp (argv[0], "--char"))
+ {
+ char_mode = 1;
+ c = strtol (argv[1], NULL, 0);
+ argc -= 2;
+ argv += 2;
+ }
+
+ limit = argc ? atoi(argv[0]) : 0;
+
+ srand(getpid());
+
+ for (i=0; !limit || i < limit; i++ )
+ {
+ if (char_mode)
+ {
+ putchar (c);
+ }
+ else
+ {
+#ifdef HAVE_RAND
+ c = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
+#else
+ c = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
+#endif
+ putchar (c);
+ }
+ }
+ return 0;
+}
diff --git a/tools/pgpgroup-to-gpggroup b/tools/pgpgroup-to-gpggroup
new file mode 100755
index 000000000..5ea9990b6
--- /dev/null
+++ b/tools/pgpgroup-to-gpggroup
@@ -0,0 +1,42 @@
+#!/usr/bin/perl -w
+
+# pgpgroup-to-gpggroup - convert PGP groups to GnuPG groups
+# Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This program 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 program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# This program requires a PGP command line program that supports
+# groups (note that the PGP 8 command line doesn't).
+
+$pgp="pgp -gvv 2>/dev/null";
+
+open(PGP,"$pgp|") || die "Unable to call PGP: $!";
+
+while(<PGP>)
+{
+ # If the line begins with a ">", then it is a new group.
+
+ if(/^ > (\S+)/)
+ {
+ print "\ngroup $1 = ";
+ }
+ elsif(/\s+(0x\S+)/)
+ {
+ print "$1 ";
+ }
+}
+
+print "\n";
+close(PGP);