aboutsummaryrefslogtreecommitdiffstats
path: root/keyserver/gpgkeys_kdns.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyserver/gpgkeys_kdns.c')
-rw-r--r--keyserver/gpgkeys_kdns.c444
1 files changed, 0 insertions, 444 deletions
diff --git a/keyserver/gpgkeys_kdns.c b/keyserver/gpgkeys_kdns.c
deleted file mode 100644
index 14651f993..000000000
--- a/keyserver/gpgkeys_kdns.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/* gpgkeys_kdns.c - Fetch a key via the GnuPG specific KDNS scheme.
- * 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/>.
- */
-
-#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>
-# ifndef HAVE_ADNS_FREE
-# define adns_free free
-# endif
-#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;
-
-/* Flag indicating that a TCP connection should be used. */
-static int kdns_usevc;
-
-
-
-/* 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|(kdns_usevc?adns_qf_usevc:0),
- &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);
- adns_free (answer);
- xfree (name);
- return ret;
-}
-
-
-/* Print some help. */
-static void
-show_help (FILE *fp)
-{
- fputs (PGM" ("GNUPG_NAME") " 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"
- "If a long answer is expected add the parameter \"usevc=1\".\n"
- "\n", fp);
- fputs ("Example: A query for \"[email protected]\" with\n"
- " kdns://10.0.0.1/example.net?at=_key&usevc=1\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_NAME") " 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;
- }
-
- if (opt->verbose)
- {
- 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))
- kdns_at_repl = p+3;
- else if (!strncmp (p, "usevc=", 6))
- kdns_usevc = !!atoi (p+6);
- }
- 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 = "";
-
- if (opt->verbose)
- {
- fprintf (console, PGM": kdns_root=%s\n", kdns_root);
- fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl);
- fprintf (console, PGM": kdns_usevc=%d\n", kdns_usevc);
- }
-
- 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;
-}