minix/external/bsd/bind/dist/contrib/zkt-1.1.3/zkt-ls.c
David van Moolenbroek 00b67f09dd Import NetBSD named(8)
Also known as ISC bind.  This import adds utilities such as host(1),
dig(1), and nslookup(1), as well as many other tools and libraries.

Change-Id: I035ca46e64f1965d57019e773f4ff0ef035e4aa3
2017-03-21 22:00:06 +00:00

442 lines
14 KiB
C

/* $NetBSD: zkt-ls.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
/*****************************************************************
**
** @(#) zkt-ls.c (c) Jan 2010 Holger Zuleger hznet.de
**
** Secure DNS zone key tool
** A command to list dnssec keys
**
** Copyright (c) 2005 - 2010, Holger Zuleger HZnet. All rights reserved.
**
** This software is open source.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
**
** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************/
# include <stdio.h>
# include <stdlib.h> /* abort(), exit(), ... */
# include <string.h>
# include <dirent.h>
# include <assert.h>
# include <unistd.h>
# include <ctype.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "config_zkt.h"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
# include <getopt.h>
#endif
# include "debug.h"
# include "misc.h"
# include "strlist.h"
# include "zconf.h"
# include "dki.h"
# include "tcap.h"
# include "zkt.h"
extern int optopt;
extern int opterr;
extern int optind;
extern char *optarg;
const char *progname;
char *labellist = NULL;
int headerflag = 1;
int ageflag = 0;
int lifetime = 0;
int lifetimeflag = 0;
int timeflag = 1;
int exptimeflag = 0;
int pathflag = 0;
int kskflag = 1;
int zskflag = 1;
int ljustflag = 0;
int subdomain_before_parent = 1;
static int dirflag = 0;
static int recflag = RECURSIVE;
static int trustedkeyflag = 0;
static int managedkeyflag = 0;
static const char *view = "";
static const char *term = NULL;
#if defined(COLOR_MODE) && COLOR_MODE
# define short_options ":HKTMV:afC::c:O:dhkLl:prstez"
#else
# define short_options ":HKTMV:af:c:O:dhkLl:prstez"
#endif
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
static struct option long_options[] = {
{"list-dnskeys", no_argument, NULL, 'K'},
{"list-trustedkeys", no_argument, NULL, 'T'},
{"list-managedkeys", no_argument, NULL, 'M'},
{"ksk", no_argument, NULL, 'k'},
{"zsk", no_argument, NULL, 'z'},
{"age", no_argument, NULL, 'a'},
{"lifetime", no_argument, NULL, 'f'},
{"time", no_argument, NULL, 't'},
{"expire", no_argument, NULL, 'e'},
{"recursive", no_argument, NULL, 'r'},
{"leftjust", no_argument, NULL, 'L'},
{"label-list", no_argument, NULL, 'l'},
{"path", no_argument, NULL, 'p'},
{"sort", no_argument, NULL, 's'},
{"subdomain", no_argument, NULL, 's'},
{"nohead", no_argument, NULL, 'h'},
{"directory", no_argument, NULL, 'd'},
#if defined(COLOR_MODE) && COLOR_MODE
{"color", optional_argument, NULL, 'C'},
#endif
{"config", required_argument, NULL, 'c'},
{"option", required_argument, NULL, 'O'},
{"config-option", required_argument, NULL, 'O'},
{"view", required_argument, NULL, 'V' },
{"help", no_argument, NULL, 'H'},
{0, 0, 0, 0}
};
#endif
static int parsedirectory (const char *dir, dki_t **listp, int sub_before);
static void parsefile (const char *file, dki_t **listp, int sub_before);
static void usage (char *mesg, zconf_t *cp);
static void setglobalflags (zconf_t *config)
{
recflag = config->recursive;
ageflag = config->printage;
timeflag = config->printtime;
ljustflag = config->ljust;
term = config->colorterm;
if ( term && *term == '\0' )
term = getenv ("TERM");
}
int main (int argc, char *argv[])
{
dki_t *data = NULL;
int c;
int opt_index;
int action;
const char *file;
const char *defconfname = NULL;
char *p;
char str[254+1];
zconf_t *config;
progname = *argv;
if ( (p = strrchr (progname, '/')) )
progname = ++p;
view = getnameappendix (progname, "zkt-ls");
defconfname = getdefconfname (view);
config = loadconfig ("", (zconf_t *)NULL); /* load built in config */
if ( fileexist (defconfname) ) /* load default config file */
config = loadconfig (defconfname, config);
if ( config == NULL )
fatal ("Out of memory\n");
setglobalflags (config);
opterr = 0;
opt_index = 0;
action = 0;
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
while ( (c = getopt_long (argc, argv, short_options, long_options, &opt_index)) != -1 )
#else
while ( (c = getopt (argc, argv, short_options)) != -1 )
#endif
{
switch ( c )
{
#if defined(COLOR_MODE) && COLOR_MODE
case 'C': /* color mode on; optional with terminal name */
if ( optarg )
term = optarg;
else
term = getenv ("TERM");
break;
#endif
case 'M':
managedkeyflag = 1;
subdomain_before_parent = 0;
zskflag = pathflag = 0;
action = c;
break;
case 'T':
trustedkeyflag = 1;
subdomain_before_parent = 0;
zskflag = pathflag = 0;
/* fall through */
case 'H':
case 'K':
case 'Z':
action = c;
break;
case 'a': /* age */
ageflag = !ageflag;
break;
case 'f': /* key lifetime */
lifetimeflag = !lifetimeflag;
break;
case 'V': /* view name */
view = optarg;
defconfname = getdefconfname (view);
if ( fileexist (defconfname) ) /* load default config file */
config = loadconfig (defconfname, config);
if ( config == NULL )
fatal ("Out of memory\n");
setglobalflags (config);
break;
case 'c':
config = loadconfig (optarg, config);
setglobalflags (config);
checkconfig (config);
break;
case 'O': /* read option from commandline */
config = loadconfig_fromstr (optarg, config);
setglobalflags (config);
checkconfig (config);
break;
case 'd': /* ignore directory arg */
dirflag = 1;
break;
case 'h': /* print no headline */
headerflag = 0;
break;
case 'k': /* ksk only */
zskflag = 0;
break;
case 'L': /* ljust */
ljustflag = !ljustflag;
break;
case 'l': /* label list */
labellist = prepstrlist (optarg, LISTDELIM);
if ( labellist == NULL )
fatal ("Out of memory\n");
break;
case 'p': /* print path */
pathflag = 1;
break;
case 'r': /* switch recursive flag */
recflag = !recflag;
break;
case 's': /* switch subdomain sorting flag */
subdomain_before_parent = !subdomain_before_parent;
break;
case 't': /* time */
timeflag = !timeflag;
break;
case 'e': /* expire time */
exptimeflag = !exptimeflag;
break;
case 'z': /* zsk only */
kskflag = 0;
break;
case ':':
snprintf (str, sizeof(str), "option \"-%c\" requires an argument.\n",
optopt);
usage (str, config);
break;
case '?':
if ( isprint (optopt) )
snprintf (str, sizeof(str), "Unknown option \"-%c\".\n",
optopt);
else
snprintf (str, sizeof (str), "Unknown option char \\x%x.\n",
optopt);
usage (str, config);
break;
default:
abort();
}
}
if ( kskflag == 0 && zskflag == 0 )
kskflag = zskflag = 1;
tc_init (stdout, term);
c = optind;
do {
if ( c >= argc ) /* no args left */
file = config->zonedir; /* use default directory */
else
file = argv[c++];
if ( is_directory (file) )
parsedirectory (file, &data, subdomain_before_parent);
else
parsefile (file, &data, subdomain_before_parent);
} while ( c < argc ); /* for all arguments */
switch ( action )
{
case 'H':
usage ("", config);
case 'K':
zkt_list_dnskeys (data);
break;
case 'T':
zkt_list_trustedkeys (data);
break;
case 'M':
zkt_list_managedkeys (data);
break;
default:
zkt_list_keys (data);
}
tc_end (stdout, term);
return 0;
}
# define sopt_usage(mesg, value) fprintf (stderr, mesg, value)
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
# define lopt_usage(mesg, value) fprintf (stderr, mesg, value)
# define loptstr(lstr, sstr) lstr
#else
# define lopt_usage(mesg, value)
# define loptstr(lstr, sstr) sstr
#endif
static void usage (char *mesg, zconf_t *cp)
{
fprintf (stderr, "Secure DNS Zone Key Tool %s\n", ZKT_VERSION);
fprintf (stderr, "\n");
fprintf (stderr, "List keys in current or given directory (-r for recursive mode)\n");
sopt_usage ("\tusage: %s [-adefhkLprtzC] [-c config] [file|dir ...]\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, "List public part of keys in DNSKEY RR format\n");
sopt_usage ("\tusage: %s -K [-dhkrz] [-c config] [file|dir ...]\n", progname);
lopt_usage ("\tusage: %s --list-dnskeys [-dhkzr] [-c config] [file|dir ...]\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, "List keys (output is suitable for trusted-keys section)\n");
sopt_usage ("\tusage: %s -T [-dhrz] [-c config] [file|dir ...]\n", progname);
lopt_usage ("\tusage: %s --list-trustedkeys [-dhzr] [-c config] [file|dir ...]\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, "List managed keys (output is suitable for managed-keys section)\n");
sopt_usage ("\tusage: %s -M [-dhrz] [-c config] [file|dir ...]\n", progname);
lopt_usage ("\tusage: %s --list-managedkeys [-dhzr] [-c config] [file|dir ...]\n", progname);
fprintf (stderr, "\n");
fprintf (stderr, "General options \n");
fprintf (stderr, "\t-c file%s", loptstr (", --config=file\n", ""));
fprintf (stderr, "\t\t read config from <file> instead of %s\n", CONFIG_FILE);
fprintf (stderr, "\t-O optstr%s", loptstr (", --config-option=\"optstr\"\n", ""));
fprintf (stderr, "\t\t read config options from commandline\n");
fprintf (stderr, "\t-h%s\t no headline or trusted/managed-key section header/trailer in -T/-M mode\n", loptstr (", --nohead", "\t"));
fprintf (stderr, "\t-d%s\t skip directory arguments\n", loptstr (", --directory", "\t"));
fprintf (stderr, "\t-L%s\t print the domain name left justified (default: %s)\n", loptstr (", --leftjust", "\t"), ljustflag ? "on": "off");
fprintf (stderr, "\t-l list%s", loptstr (", --label=\"list\"\n\t", ""));
fprintf (stderr, "\t\t print out only zone keys from the given domain list\n");
fprintf (stderr, "\t-C[term]%s", loptstr (", --color[=\"term\"]\n\t", ""));
fprintf (stderr, "\t\t turn color mode on \n");
fprintf (stderr, "\t-p%s\t show path of keyfile / create key in current directory\n", loptstr (", --path", "\t"));
fprintf (stderr, "\t-r%s\t recursive mode on/off (default: %s)\n", loptstr(", --recursive", "\t"), recflag ? "on": "off");
fprintf (stderr, "\t-s%s\t change sorting of subdomains\n", loptstr(", --subdomain", "\t"));
fprintf (stderr, "\t-a%s\t print age of key (default: %s)\n", loptstr (", --age", "\t"), ageflag ? "on": "off");
fprintf (stderr, "\t-t%s\t print key generation time (default: %s)\n", loptstr (", --time", "\t"),
timeflag ? "on": "off");
fprintf (stderr, "\t-e%s\t print key expiration time\n", loptstr (", --expire", "\t"));
fprintf (stderr, "\t-f%s\t print key lifetime\n", loptstr (", --lifetime", "\t"));
fprintf (stderr, "\t-k%s\t key signing keys only\n", loptstr (", --ksk", "\t"));
fprintf (stderr, "\t-z%s\t zone signing keys only\n", loptstr (", --zsk", "\t"));
if ( mesg && *mesg )
fprintf (stderr, "%s\n", mesg);
exit (1);
}
static int parsedirectory (const char *dir, dki_t **listp, int sub_before)
{
dki_t *dkp;
DIR *dirp;
struct dirent *dentp;
char path[MAX_PATHSIZE+1];
if ( dirflag )
return 0;
dbg_val ("directory: opendir(%s)\n", dir);
if ( (dirp = opendir (dir)) == NULL )
return 0;
while ( (dentp = readdir (dirp)) != NULL )
{
if ( is_dotfilename (dentp->d_name) )
continue;
dbg_val ("directory: check %s\n", dentp->d_name);
pathname (path, sizeof (path), dir, dentp->d_name, NULL);
if ( is_directory (path) && recflag )
{
dbg_val ("directory: recursive %s\n", path);
parsedirectory (path, listp, sub_before);
}
else if ( is_keyfilename (dentp->d_name) )
if ( (dkp = dki_read (dir, dentp->d_name)) )
{
// fprintf (stderr, "parsedir: tssearch (%d %s)\n", dkp, dkp->name);
#if defined (USE_TREE) && USE_TREE
dki_tadd (listp, dkp, sub_before);
#else
dki_add (listp, dkp);
#endif
}
}
closedir (dirp);
return 1;
}
static void parsefile (const char *file, dki_t **listp, int sub_before)
{
char path[MAX_PATHSIZE+1];
dki_t *dkp;
/* file arg contains path ? ... */
file = splitpath (path, sizeof (path), file); /* ... then split of */
if ( is_keyfilename (file) ) /* plain file name looks like DNS key file ? */
{
if ( (dkp = dki_read (path, file)) ) /* read DNS key file ... */
#if defined (USE_TREE) && USE_TREE
dki_tadd (listp, dkp, sub_before); /* ... and add to tree */
#else
dki_add (listp, dkp); /* ... and add to list */
#endif
else
error ("error parsing %s: (%s)\n", file, dki_geterrstr());
}
}