summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--common/ChangeLog13
-rw-r--r--common/Makefile.am5
-rw-r--r--common/b64enc.c157
-rw-r--r--common/pka.c4
-rw-r--r--common/t-b64.c87
-rw-r--r--common/util.h1
-rw-r--r--configure.ac36
-rw-r--r--g10/ChangeLog6
-rw-r--r--g10/getkey.c8
-rw-r--r--g10/keyserver.c10
-rw-r--r--g10/pkclist.c1
-rw-r--r--keyserver/ChangeLog7
-rw-r--r--keyserver/Makefile.am10
-rw-r--r--keyserver/gpgkeys_kdns.c435
-rw-r--r--keyserver/no-libgcrypt.c5
-rw-r--r--po/de.po4
17 files changed, 768 insertions, 27 deletions
diff --git a/ChangeLog b/ChangeLog
index f2f0af494..75f89cbcc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,13 @@
+2008-04-07 Werner Koch <wk@g10code.com>
+
+ * configure.ac (ADNSLIBS): Test for adns.
+ (GPGKEYS_KDNS): New.
+
2008-04-01 Werner Koch <wk@g10code.com>
* configure.ac: Require curl 7.10 (Oct 1 2002) or later as we use
curl_version_info().
+ (AC_INIT): Fix quoting.
2008-03-27 Werner Koch <wk@g10code.com>
diff --git a/common/ChangeLog b/common/ChangeLog
index 78baf7a57..ab68709cc 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,12 @@
+2008-04-07 Werner Koch <wk@g10code.com>
+
+ * b64enc.c (b64enc_start): Detect PGP mode.
+ (b64enc_finish): Write PGP CRC.
+ * util.h (struct b64state): Add field CRC.
+ * t-b64.c: New.
+
+ * pka.c (get_pka_info): Use xtrymalloc and check result.
+
2008-03-25 Werner Koch <wk@g10code.com>
* localename.c: Strip all W32 code. Include w32help.h.
@@ -1168,8 +1177,8 @@
(atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New.
- Copyright 2001, 2002, 2003, 2004, 2005, 2006,
- 2007 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008 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
diff --git a/common/Makefile.am b/common/Makefile.am
index e9c532521..f8283a6a9 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -108,7 +108,7 @@ status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h
# Module tests
#
module_tests = t-convert t-gettime t-sysutils t-sexputil
-module_maint_tests = t-helpfile
+module_maint_tests = t-helpfile t-b64
t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
@@ -118,4 +118,7 @@ t_gettime_LDADD = $(t_common_ldadd)
t_sysutils_LDADD = $(t_common_ldadd)
t_helpfile_LDADD = $(t_common_ldadd)
t_sexputil_LDADD = $(t_common_ldadd)
+t_b64_LDADD = $(t_common_ldadd)
+
+
diff --git a/common/b64enc.c b/common/b64enc.c
index e886f9403..4722bd1e1 100644
--- a/common/b64enc.c
+++ b/common/b64enc.c
@@ -1,5 +1,5 @@
/* b64enc.c - Simple Base64 encoder.
- * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -30,20 +30,121 @@
#define B64ENC_DID_HEADER 1
#define B64ENC_DID_TRAILER 2
#define B64ENC_NO_LINEFEEDS 16
-
+#define B64ENC_USE_PGPCRC 32
/* The base-64 character list */
static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
+/* Stuff required to create the OpenPGP CRC. This crc_table has been
+ created using this code:
+
+ #include <stdio.h>
+ #include <stdint.h>
+
+ #define CRCPOLY 0x864CFB
+
+ int
+ main (void)
+ {
+ int i, j;
+ uint32_t t;
+ uint32_t crc_table[256];
+
+ crc_table[0] = 0;
+ for (i=j=0; j < 128; j++ )
+ {
+ t = crc_table[j];
+ if ( (t & 0x00800000) )
+ {
+ t <<= 1;
+ crc_table[i++] = t ^ CRCPOLY;
+ crc_table[i++] = t;
+ }
+ else
+ {
+ t <<= 1;
+ crc_table[i++] = t;
+ crc_table[i++] = t ^ CRCPOLY;
+ }
+ }
+
+ puts ("static const u32 crc_table[256] = {");
+ for (i=j=0; i < 256; i++)
+ {
+ printf ("%s 0x%08lx", j? "":" ", (unsigned long)crc_table[i]);
+ if (i != 255)
+ {
+ putchar (',');
+ if ( ++j > 5)
+ {
+ j = 0;
+ putchar ('\n');
+ }
+ }
+ }
+ puts ("\n};");
+ return 0;
+ }
+*/
+#define CRCINIT 0xB704CE
+static const u32 crc_table[256] = {
+ 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a,
+ 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf,
+ 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272,
+ 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e,
+ 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa,
+ 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f,
+ 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b,
+ 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7,
+ 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a,
+ 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af,
+ 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29,
+ 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5,
+ 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1,
+ 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, 0x30563856, 0x30d074ad,
+ 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099,
+ 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375,
+ 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821,
+ 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4,
+ 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049,
+ 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5,
+ 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791,
+ 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52,
+ 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66,
+ 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a,
+ 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337,
+ 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2,
+ 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6,
+ 0x62b54340, 0x62330fbb, 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a,
+ 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e,
+ 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132,
+ 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506,
+ 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea,
+ 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c,
+ 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9,
+ 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604,
+ 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8,
+ 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc,
+ 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69,
+ 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d,
+ 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1,
+ 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c,
+ 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9,
+ 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538
+};
+
+
/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
and not an empty string, this string will be used as the title for
the armor lines, with TITLE being an empty string, we don't write
the header lines and furthermore even don't write any linefeeds.
- With TITLE beeing NULL, we merely don't write header but make sure
- that lines are not too long. Note, that we don't write any output
- unless at least one byte get written using b64enc_write. */
+ If TITLE starts with "PGP " the OpenPGP CRC checksum will be
+ written as well. With TITLE beeing NULL, we merely don't write
+ header but make sure that lines are not too long. Note, that we
+ don't write any output unless at least one byte get written using
+ b64enc_write. */
gpg_error_t
b64enc_start (struct b64state *state, FILE *fp, const char *title)
{
@@ -53,9 +154,14 @@ b64enc_start (struct b64state *state, FILE *fp, const char *title)
state->flags |= B64ENC_NO_LINEFEEDS;
else if (title)
{
+ if (!strncmp (title, "PGP ", 4))
+ {
+ state->flags |= B64ENC_USE_PGPCRC;
+ state->crc = CRCINIT;
+ }
state->title = xtrystrdup (title);
if (!state->title)
- return gpg_error_from_syserror ();
+ return gpg_error_from_syserror ();
}
return 0;
}
@@ -88,7 +194,11 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
goto write_error;
+ if ( (state->flags & B64ENC_USE_PGPCRC)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
}
+
state->flags |= B64ENC_DID_HEADER;
}
@@ -96,7 +206,17 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
quad_count = state->quad_count;
assert (idx < 4);
memcpy (radbuf, state->radbuf, idx);
-
+
+ if ( (state->flags & B64ENC_USE_PGPCRC) )
+ {
+ size_t n;
+ u32 crc = state->crc;
+
+ for (p=buffer, n=nbytes; n; p++, n-- )
+ crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p];
+ state->crc = (crc & 0x00ffffff);
+ }
+
for (p=buffer; nbytes; p++, nbytes--)
{
radbuf[idx++] = *p;
@@ -138,6 +258,7 @@ b64enc_finish (struct b64state *state)
unsigned char radbuf[4];
int idx, quad_count;
FILE *fp;
+ char tmp[4];
if (!(state->flags & B64ENC_DID_HEADER))
goto cleanup;
@@ -151,8 +272,6 @@ b64enc_finish (struct b64state *state)
if (idx)
{
- char tmp[4];
-
tmp[0] = bintoasc[(*radbuf>>2)&077];
if (idx == 1)
{
@@ -186,6 +305,26 @@ b64enc_finish (struct b64state *state)
&& !(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
goto write_error;
+
+ if ( (state->flags & B64ENC_USE_PGPCRC) )
+ {
+ /* Write the CRC. */
+ putc ('=', fp);
+ radbuf[0] = state->crc >>16;
+ radbuf[1] = state->crc >> 8;
+ radbuf[2] = state->crc;
+ tmp[0] = bintoasc[(*radbuf>>2)&077];
+ tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
+ tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
+ tmp[3] = bintoasc[radbuf[2]&077];
+ for (idx=0; idx < 4; idx++)
+ putc (tmp[idx], fp);
+ if (ferror (fp))
+ goto write_error;
+ if (!(state->flags & B64ENC_NO_LINEFEEDS)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
+ }
if (state->title)
{
diff --git a/common/pka.c b/common/pka.c
index f592cb037..79a0bc3f5 100644
--- a/common/pka.c
+++ b/common/pka.c
@@ -119,7 +119,9 @@ get_pka_info (const char *address, unsigned char *fpr)
if (!domain || domain == address || !domain[1])
return NULL; /* invalid mail address given. */
- name = malloc (strlen (address) + 5 + 1);
+ name = xtrymalloc (strlen (address) + 5 + 1);
+ if (!name)
+ return NULL;
memcpy (name, address, domain - address);
strcpy (stpcpy (name + (domain-address), "._pka."), domain+1);
diff --git a/common/t-b64.c b/common/t-b64.c
new file mode 100644
index 000000000..0f26ab31e
--- /dev/null
+++ b/common/t-b64.c
@@ -0,0 +1,87 @@
+/* t-b64.c - Module tests for b64enc.c and b64dec.c
+ * Copyright (C) 2008 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+
+ As of now this is only a test program for manual tests.
+
+ */
+
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#define pass() do { ; } while(0)
+#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
+ __FILE__,__LINE__, (a)); \
+ errcount++; \
+ } while(0)
+
+static int verbose;
+static int errcount;
+
+static void
+test_b64enc_pgp (const char *string)
+{
+ gpg_error_t err;
+ struct b64state state;
+
+ if (!string)
+ string = "a";
+
+ err = b64enc_start (&state, stdout, "PGP MESSAGE");
+ if (err)
+ fail (1);
+
+ err = b64enc_write (&state, string, strlen (string));
+ if (err)
+ fail (2);
+
+ err = b64enc_finish (&state);
+ if (err)
+ fail (3);
+
+ pass ();
+}
+
+
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc)
+ { argc--; argv++; }
+ if (argc && !strcmp (argv[0], "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+
+ test_b64enc_pgp (argc? *argv: NULL);
+
+ return !!errcount;
+}
+
diff --git a/common/util.h b/common/util.h
index 53a56a336..e479cfc4c 100644
--- a/common/util.h
+++ b/common/util.h
@@ -152,6 +152,7 @@ struct b64state
FILE *fp;
char *title;
unsigned char radbuf[4];
+ u32 crc;
};
gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title);
gpg_error_t b64enc_write (struct b64state *state,
diff --git a/configure.ac b/configure.ac
index 4f0881a81..4ad65a668 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# configure.ac - for GnuPG 2.0
# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-# 2006, 2007 Free Software Foundation, Inc.
+# 2006, 2007, 2008 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
@@ -30,7 +30,8 @@ m4_define([my_issvn], [yes])
m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \
|| echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')]))
-AC_INIT([gnupg], my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision]),
+AC_INIT([gnupg],
+ [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])],
[bug-gnupg@gnupg.org])
# Set development_version to yes if the minor number is odd or you
# feel that the default check for a development version is not
@@ -69,6 +70,7 @@ have_libassuan=no
have_ksba=no
have_pth=no
have_libusb=no
+have_adns=no
use_bzip2=yes
use_exec=yes
@@ -759,6 +761,7 @@ if test x"$use_dns_pka" = xyes || test x"$use_dns_srv" = xyes \
# Make sure that the BIND 4 resolver interface is workable before
# enabling any code that calls it. At some point I'll rewrite the
# code to use the BIND 8 resolver API.
+ # We might also want to use adns instead.
AC_MSG_CHECKING([whether the resolver is usable])
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <sys/types.h>
@@ -822,6 +825,30 @@ AC_SUBST(DNSLIBS)
AM_CONDITIONAL(USE_DNS_SRV, test x"$use_dns_srv" = xyes)
+
+#
+# Check for ADNS.
+#
+_cppflags="${CPPFLAGS}"
+_ldflags="${LDFLAGS}"
+AC_ARG_WITH(adns,
+ AC_HELP_STRING([--with-adns=DIR],
+ [look for the adns library in DIR]),
+ [if test -d "$withval"; then
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ fi])
+AC_CHECK_HEADERS(adns.h,
+ AC_CHECK_LIB(adns, adns_init,
+ [have_adns=yes],
+ [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}]),
+ [CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}])
+if test "$have_adns" = "yes"; then
+ ADNSLIBS="-ladns"
+fi
+AC_SUBST(ADNSLIBS)
+
+
#
# Check for LDAP
#
@@ -1264,6 +1291,11 @@ estream_INIT
#
# Decide what to build
#
+if test "$have_adns" = "yes"; then
+ AC_SUBST(GPGKEYS_KDNS, "gpg2keys_kdns$EXEEXT")
+fi
+
+
missing_pth=no
if test $have_ksba = no; then
build_gpgsm=no
diff --git a/g10/ChangeLog b/g10/ChangeLog
index b4f2720b3..f8f22256a 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-07 Werner Koch <wk@g10code.com>
+
+ * keyserver.c (parse_keyserver_uri): Allow a default host name.
+
+ * getkey.c (get_pubkey_byname): Replace sprintf by bin2hex.
+
2008-04-02 Werner Koch <wk@g10code.com>
* gpg.c (main): Do not allow DSA2 with a too old Libgcrypt.
diff --git a/g10/getkey.c b/g10/getkey.c
index c1d21f109..47cf22ea3 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1012,9 +1012,8 @@ get_pubkey_byname (PKT_public_key *pk,
requirement as the URL might point to a key put in by an
attacker. By forcing the use of the fingerprint, we
won't use the attacker's key here. */
- if(rc==0 && fpr)
+ if (!rc && fpr)
{
- int i;
char fpr_string[MAX_FINGERPRINT_LEN*2+1];
assert(fpr_len<=MAX_FINGERPRINT_LEN);
@@ -1022,9 +1021,8 @@ get_pubkey_byname (PKT_public_key *pk,
free_strlist(namelist);
namelist=NULL;
- for(i=0;i<fpr_len;i++)
- sprintf(fpr_string+2*i,"%02X",fpr[i]);
-
+ bin2hex (fpr, fpr_len, fpr_string);
+
if(opt.verbose)
log_info("auto-key-locate found fingerprint %s\n",fpr_string);
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 9a4e08483..12be4c2f0 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -330,7 +330,15 @@ parse_keyserver_uri(const char *string,int require_scheme,
keyserver->scheme=xstrdup("hkp");
}
- if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
+ if (uri[0]=='/' && uri[1]=='/' && uri[2] == '/')
+ {
+ /* Three slashes means network path with a default host name.
+ This is a hack because it does not crok all possible
+ combiantions. We should better repalce all code bythe parser
+ from http.c. */
+ keyserver->path = xstrdup (uri+2);
+ }
+ else if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
{
/* Two slashes means network path. */
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 6b7401826..cb50ae29b 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -774,7 +774,6 @@ expand_group(strlist_t input)
Bit 1: This is a hidden recipient.
USE is the desired use for the key - usually PUBKEY_USAGE_ENC.
- RET_PK_LIST.
On success a list of keys is stored at the address RET_PK_LIST; the
caller must free this list. On error the value at this address is
diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog
index be26f21dc..8f4752465 100644
--- a/keyserver/ChangeLog
+++ b/keyserver/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-07 Werner Koch <wk@g10code.com>
+
+ * gpgkeys_kdns.c: New.
+ * Makefile.am: Support kdns.
+
+ * no-libgcrypt.c (gcry_strdup): Fix. It was not used.
+
2008-03-25 Werner Koch <wk@g10code.com>
* gpgkeys_ldap.c (build_attrs): Take care of char defaulting to
diff --git a/keyserver/Makefile.am b/keyserver/Makefile.am
index 103e82f42..b25c294cb 100644
--- a/keyserver/Makefile.am
+++ b/keyserver/Makefile.am
@@ -20,7 +20,8 @@
# to gpg2keys_foo to allow for a non-conflicting installation of
# gnupg1 and gnupg2. Having the same names for the helpers would
# otherwise lead to trouble when to uninstall one of them.
-EXTRA_PROGRAMS = gpg2keys_ldap gpg2keys_hkp gpg2keys_finger gpg2keys_curl
+EXTRA_PROGRAMS = gpg2keys_ldap gpg2keys_hkp gpg2keys_finger gpg2keys_curl \
+ gpg2keys_kdns
EXTRA_SCRIPTS = gpg2keys_mailto
AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl
@@ -30,7 +31,7 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
include $(top_srcdir)/am/cmacros.am
libexec_PROGRAMS = $(GPGKEYS_LDAP) $(GPGKEYS_HKP) $(GPGKEYS_FINGER) \
- $(GPGKEYS_CURL)
+ $(GPGKEYS_CURL) $(GPGKEYS_KDNS)
libexec_SCRIPTS = $(GPGKEYS_MAILTO)
noinst_SCRIPTS = gpg2keys_test
@@ -47,6 +48,11 @@ gpg2keys_finger_CPPFLAGS = $(AM_CPPFLAGS)
gpg2keys_finger_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
$(NETLIBS) $(other_libs)
+gpg2keys_kdns_SOURCES = gpgkeys_kdns.c ksutil.c ksutil.h no-libgcrypt.c
+gpg2keys_kdns_CPPFLAGS = $(AM_CPPFLAGS)
+gpg2keys_kdns_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+ $(ADNSLIBS) $(NETLIBS) $(other_libs)
+
gpg2keys_curl_SOURCES = gpgkeys_curl.c ksutil.c ksutil.h no-libgcrypt.c
gpg2keys_hkp_SOURCES = gpgkeys_hkp.c ksutil.c ksutil.h no-libgcrypt.c
diff --git a/keyserver/gpgkeys_kdns.c b/keyserver/gpgkeys_kdns.c
new file mode 100644
index 000000000..522f1c823
--- /dev/null
+++ b/keyserver/gpgkeys_kdns.c
@@ -0,0 +1,435 @@
+/* gpgkeys_kdns.c - Fetch a key via the GnuPG specific KDNS scheme.
+ * Copyright (C) 2008 g10 Code GmbH
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+#include <assert.h>
+#ifdef HAVE_ADNS_H
+# include <adns.h>
+#endif
+
+#define INCLUDED_BY_MAIN_MODULE 1
+#include "util.h"
+#include "keyserver.h"
+#include "ksutil.h"
+
+/* Our own name. */
+#define PGM "gpgkeys_kdns"
+
+/* getopt(3) requires declarion of some global variables. */
+extern char *optarg;
+extern int optind;
+
+/* Convenience variables usually intialized withn std{in,out,err}. */
+static FILE *input, *output, *console;
+
+/* Standard keyserver module options. */
+static struct ks_options *opt;
+
+/* The flags we pass to adns_init: Do not allow any environment
+ variables and for now enable debugging. */
+#define MY_ADNS_INITFLAGS (adns_if_noenv)
+
+
+/* ADNS has no support for CERT yes. */
+#define my_adns_r_cert 37
+
+/* The root of the KDNS tree. */
+static const char *kdns_root;
+
+/* The replacement string for the at sign. */
+static const char *kdns_at_repl;
+
+
+
+
+
+/* Retrieve one key. ADDRESS should be an RFC-2822 addr-spec. */
+static int
+get_key (adns_state adns_ctx, char *address)
+{
+ int ret = KEYSERVER_INTERNAL_ERROR;
+ const char *domain;
+ char *name = NULL;
+ adns_answer *answer = NULL;
+ const unsigned char *data;
+ int datalen;
+ struct b64state b64state;
+ char *p;
+
+ domain = strrchr (address, '@');
+ if (!domain || domain == address || !domain[1])
+ {
+ fprintf (console, PGM": invalid mail address `%s'\n", address);
+ ret = KEYSERVER_GENERAL_ERROR;
+ goto leave;
+ }
+ name = xtrymalloc (strlen (address) + strlen (kdns_at_repl)
+ + 1 + strlen (kdns_root) + 1);
+ if (!name)
+ goto leave;
+ memcpy (name, address, domain - address);
+ p = stpcpy (name + (domain-address), ".");
+ if (*kdns_at_repl)
+ p = stpcpy (stpcpy (p, kdns_at_repl), ".");
+ p = stpcpy (p, domain+1);
+ if (*kdns_root)
+ strcpy (stpcpy (p, "."), kdns_root);
+
+ fprintf (output,"NAME %s BEGIN\n", address);
+ if (opt->verbose > 2)
+ fprintf(console, PGM": looking up `%s'\n", name);
+
+
+ if ( adns_synchronous (adns_ctx, name, (adns_r_unknown | my_adns_r_cert),
+ adns_qf_quoteok_query,
+ &answer) )
+ {
+ fprintf (console, PGM": DNS query failed: %s\n", strerror (errno));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ if (answer->status != adns_s_ok)
+ {
+ fprintf (console, PGM": DNS query returned: %s (%s)\n",
+ adns_strerror (answer->status),
+ adns_errabbrev (answer->status));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ datalen = answer->rrs.byteblock->len;
+ data = answer->rrs.byteblock->data;
+
+ if ( opt->debug > 1 )
+ {
+ int i;
+
+ fprintf (console, "got %d bytes of data:", datalen);
+ for (i=0; i < datalen; i++)
+ {
+ if (!(i % 32))
+ fprintf (console, "\n%08x ", i);
+ fprintf (console, "%02x", data[i]);
+ }
+ putc ('\n', console);
+ }
+ if ( datalen < 5 )
+ {
+ fprintf (console, PGM": error: truncated CERT record\n");
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+
+ switch ( ((data[0]<<8)|data[1]) )
+ {
+ case 3: /* CERT type is PGP. */
+ /* (key tag and algorithm fields are ignored for this CERT type). */
+ data += 5;
+ datalen -= 5;
+ if ( datalen < 11 )
+ {
+ /* Gpg checks for a minium length of 11, thus we do the same. */
+ fprintf (console, PGM": error: OpenPGP data to short\n");
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+ if (b64enc_start (&b64state, output, "PGP PUBLIC KEY BLOCK")
+ || b64enc_write (&b64state, data, datalen)
+ || b64enc_finish (&b64state))
+ goto leave; /* Oops, base64 encoder failed. */
+ break;
+
+ default:
+ fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1]));
+ ret = KEYSERVER_KEY_NOT_FOUND;
+ goto leave;
+ }
+
+ ret = 0; /* All fine. */
+
+ leave:
+ if (ret)
+ fprintf (output, "\nNAME %s FAILED %d\n", address, ret);
+ else
+ fprintf (output, "\nNAME %s END\n", address);
+ free (answer); /* (Right, this is free and not xfree.) */
+ xfree (name);
+ return ret;
+}
+
+
+/* Print some help. */
+static void
+show_help (FILE *fp)
+{
+ fputs (PGM" (GnuPG) " VERSION"\n\n", fp);
+ fputs (" -h\thelp\n"
+ " -V\tversion\n"
+ " -o\toutput to this file\n"
+ "\n", fp);
+ fputs ("This keyserver helper accepts URLs of the form:\n"
+ " kdns://[NAMESERVER]/[ROOT][?at=[STRING]]\n"
+ "with\n"
+ " NAMESERVER used for queries (default: system standard)\n"
+ " ROOT a DNS name appended to the query (default: none)\n"
+ " STRING A string to replace the '@' (default: \".\")\n"
+ "\n", fp);
+ fputs ("Example: A query for \"hacker@gnupg.org\" with\n"
+ " kdns://10.0.0.1/example.net?at=_key?\n"
+ "setup as --auto-key-lookup does a CERT record query\n"
+ "with type PGP on the nameserver 10.0.0.1 for\n"
+ " hacker._key_.gnupg.org.example.net\n"
+ "\n", fp);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int arg;
+ int ret = KEYSERVER_INTERNAL_ERROR;
+ char line[MAX_LINE];
+ struct keylist *keylist = NULL;
+ struct keylist **keylist_tail = &keylist;
+ struct keylist *akey;
+ int failed = 0;
+ adns_state adns_ctx = NULL;
+ adns_initflags my_adns_initflags = MY_ADNS_INITFLAGS;
+ int tmprc;
+
+ /* The defaults for the KDNS name mangling. */
+ kdns_root = "";
+ kdns_at_repl = "";
+
+ console = stderr;
+
+ /* Kludge to implement standard GNU options. */
+ if (argc > 1 && !strcmp (argv[1], "--version"))
+ {
+ fputs (PGM" (GnuPG) " VERSION"\n", stdout);
+ return 0;
+ }
+ else if (argc > 1 && !strcmp (argv[1], "--help"))
+ {
+ show_help (stdout);
+ return 0;
+ }
+
+ while ( (arg = getopt (argc, argv, "hVo:")) != -1 )
+ {
+ switch(arg)
+ {
+ case 'V':
+ printf ("%d\n%s\n", KEYSERVER_PROTO_VERSION, VERSION);
+ return KEYSERVER_OK;
+
+ case 'o':
+ output = fopen (optarg,"w");
+ if (!output)
+ {
+ fprintf (console, PGM": cannot open output file `%s': %s\n",
+ optarg, strerror(errno) );
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ break;
+
+ case 'h':
+ default:
+ show_help (console);
+ return KEYSERVER_OK;
+ }
+ }
+
+ if (argc > optind)
+ {
+ input = fopen (argv[optind], "r");
+ if (!input)
+ {
+ fprintf (console, PGM": cannot open input file `%s': %s\n",
+ argv[optind], strerror(errno) );
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+ }
+
+ if (!input)
+ input = stdin;
+
+ if (!output)
+ output = stdout;
+
+ opt = init_ks_options();
+ if(!opt)
+ return KEYSERVER_NO_MEMORY;
+
+ /* Get the command and info block */
+ while ( fgets(line,MAX_LINE,input) )
+ {
+ int err;
+
+ if(line[0]=='\n')
+ break;
+
+ err = parse_ks_options (line, opt);
+ if (err > 0)
+ {
+ ret = err;
+ goto leave;
+ }
+ else if (!err)
+ continue;
+ }
+
+ if (opt->timeout && register_timeout() == -1 )
+ {
+ fprintf (console, PGM": unable to register timeout handler\n");
+ return KEYSERVER_INTERNAL_ERROR;
+ }
+
+ fprintf (console, PGM": HOST=%s\n", opt->host? opt->host:"(none)");
+ fprintf (console, PGM": PATH=%s\n", opt->path? opt->path:"(none)");
+ if (opt->path && *opt->path == '/')
+ {
+ char *p, *pend;
+
+ kdns_root = opt->path+1;
+ p = strchr (opt->path+1, '?');
+ if (p)
+ {
+ *p++ = 0;
+ do
+ {
+ pend = strchr (p, '&');
+ if (pend)
+ *pend++ = 0;
+ if (!strncmp (p, "at=", 3))
+ {
+ /* Found. */
+ kdns_at_repl = p+3;
+ break;
+ }
+ }
+ while ((p = pend));
+ }
+ }
+ if (strchr (kdns_root, '/'))
+ {
+ fprintf (console, PGM": invalid character in KDNS root\n");
+ return KEYSERVER_GENERAL_ERROR;
+ }
+ if (!strcmp (kdns_at_repl, "."))
+ kdns_at_repl = "";
+ fprintf (console, PGM": kdns_root=%s\n", kdns_root);
+ fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl);
+
+
+ if (opt->debug)
+ my_adns_initflags |= adns_if_debug;
+ if (opt->host)
+ {
+ char cfgtext[200];
+
+ snprintf (cfgtext, sizeof cfgtext, "nameserver %s\n", opt->host);
+ tmprc = adns_init_strcfg (&adns_ctx, my_adns_initflags, console,cfgtext);
+ }
+ else
+ tmprc = adns_init (&adns_ctx, my_adns_initflags, console);
+ if (tmprc)
+ {
+ fprintf (console, PGM": error initializing ADNS: %s\n",
+ strerror (errno));
+ goto leave;
+ }
+
+ if (opt->action == KS_GETNAME)
+ {
+ while ( fgets (line,MAX_LINE,input) )
+ {
+ if (line[0]=='\n' || !line[0] )
+ break;
+ line[strlen(line)-1] = 0; /* Trim the trailing LF. */
+
+ akey = xtrymalloc (sizeof *akey);
+ if (!akey)
+ {
+ fprintf (console,
+ PGM": out of memory while building key list\n");
+ ret = KEYSERVER_NO_MEMORY;
+ goto leave;
+ }
+ assert (sizeof (akey->str) > strlen(line));
+ strcpy (akey->str, line);
+ akey->next = NULL;
+ *keylist_tail = akey;
+ keylist_tail = &akey->next;
+ }
+ }
+ else
+ {
+ fprintf (console,
+ PGM": this keyserver type only supports "
+ "key retrieval by name\n");
+ goto leave;
+ }
+
+ /* Send the response */
+ fprintf (output, "VERSION %d\n", KEYSERVER_PROTO_VERSION);
+ fprintf (output, "PROGRAM %s\n\n", VERSION);
+
+ if (opt->verbose > 1)
+ {
+ if (opt->opaque)
+ fprintf (console, "User:\t\t%s\n", opt->opaque);
+ fprintf (console, "Command:\tGET\n");
+ }
+
+ for (akey = keylist; akey; akey = akey->next)
+ {
+ set_timeout (opt->timeout);
+ if ( get_key (adns_ctx, akey->str) )
+ failed++;
+ }
+ if (!failed)
+ ret = KEYSERVER_OK;
+
+
+ leave:
+ if (adns_ctx)
+ adns_finish (adns_ctx);
+ while (keylist)
+ {
+ akey = keylist->next;
+ xfree (keylist);
+ keylist = akey;
+ }
+ if (input != stdin)
+ fclose (input);
+ if (output != stdout)
+ fclose (output);
+ kdns_root = "";
+ kdns_at_repl = ".";
+ free_ks_options (opt);
+ return ret;
+}
diff --git a/keyserver/no-libgcrypt.c b/keyserver/no-libgcrypt.c
index 690a366a4..2cce156a7 100644
--- a/keyserver/no-libgcrypt.c
+++ b/keyserver/no-libgcrypt.c
@@ -49,7 +49,10 @@ gcry_xmalloc (size_t n)
char *
gcry_strdup (const char *string)
{
- return malloc (strlen (string)+1);
+ char *p = malloc (strlen (string)+1);
+ if (p)
+ strcpy (p, string);
+ return p;
}
diff --git a/po/de.po b/po/de.po
index 17fb2ce33..45a56e1ba 100644
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: gnupg-2.0.6\n"
"Report-Msgid-Bugs-To: translations@gnupg.org\n"
"POT-Creation-Date: 2008-03-27 13:41+0100\n"
-"PO-Revision-Date: 2008-03-26 09:56+0100\n"
+"PO-Revision-Date: 2008-04-02 17:50+0200\n"
"Last-Translator: Walter Koch <koch@u32.de>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
@@ -7084,7 +7084,7 @@ msgstr ""
"des X.509 Zertifikats:\n"
"\"%s\"\n"
"S/N %s, ID 0x%08lX,\n"
-"gültig von %s bis %s\\n \n"
+"gültig von %s bis %s\n"
"zu entsperren.\n"
#: sm/certlist.c:122