1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-03 12:11:33 +01:00

Minor cleanups.

Implemented key helper kdns
This commit is contained in:
Werner Koch 2008-04-07 19:31:12 +00:00
parent ba63cfa79b
commit 86f35a55d0
17 changed files with 768 additions and 27 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

87
common/t-b64.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

435
keyserver/gpgkeys_kdns.c Normal file
View File

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

View File

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

View File

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