1 /* $NetBSD: zkt-ls.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) zkt-ls.c (c) Jan 2010 Holger Zuleger hznet.de
7 ** Secure DNS zone key tool
8 ** A command to list dnssec keys
10 ** Copyright (c) 2005 - 2010, Holger Zuleger HZnet. All rights reserved.
12 ** This software is open source.
14 ** Redistribution and use in source and binary forms, with or without
15 ** modification, are permitted provided that the following conditions
18 ** Redistributions of source code must retain the above copyright notice,
19 ** this list of conditions and the following disclaimer.
21 ** Redistributions in binary form must reproduce the above copyright notice,
22 ** this list of conditions and the following disclaimer in the documentation
23 ** and/or other materials provided with the distribution.
25 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
26 ** be used to endorse or promote products derived from this software without
27 ** specific prior written permission.
29 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
33 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 ** POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************/
44 # include <stdlib.h> /* abort(), exit(), ... */
54 # include "config_zkt.h"
55 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
73 char *labellist
= NULL
;
85 int subdomain_before_parent
= 1;
87 static int dirflag
= 0;
88 static int recflag
= RECURSIVE
;
89 static int trustedkeyflag
= 0;
90 static int managedkeyflag
= 0;
91 static const char *view
= "";
92 static const char *term
= NULL
;
94 #if defined(COLOR_MODE) && COLOR_MODE
95 # define short_options ":HKTMV:afC::c:O:dhkLl:prstez"
97 # define short_options ":HKTMV:af:c:O:dhkLl:prstez"
99 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
100 static struct option long_options
[] = {
101 {"list-dnskeys", no_argument
, NULL
, 'K'},
102 {"list-trustedkeys", no_argument
, NULL
, 'T'},
103 {"list-managedkeys", no_argument
, NULL
, 'M'},
104 {"ksk", no_argument
, NULL
, 'k'},
105 {"zsk", no_argument
, NULL
, 'z'},
106 {"age", no_argument
, NULL
, 'a'},
107 {"lifetime", no_argument
, NULL
, 'f'},
108 {"time", no_argument
, NULL
, 't'},
109 {"expire", no_argument
, NULL
, 'e'},
110 {"recursive", no_argument
, NULL
, 'r'},
111 {"leftjust", no_argument
, NULL
, 'L'},
112 {"label-list", no_argument
, NULL
, 'l'},
113 {"path", no_argument
, NULL
, 'p'},
114 {"sort", no_argument
, NULL
, 's'},
115 {"subdomain", no_argument
, NULL
, 's'},
116 {"nohead", no_argument
, NULL
, 'h'},
117 {"directory", no_argument
, NULL
, 'd'},
118 #if defined(COLOR_MODE) && COLOR_MODE
119 {"color", optional_argument
, NULL
, 'C'},
121 {"config", required_argument
, NULL
, 'c'},
122 {"option", required_argument
, NULL
, 'O'},
123 {"config-option", required_argument
, NULL
, 'O'},
124 {"view", required_argument
, NULL
, 'V' },
125 {"help", no_argument
, NULL
, 'H'},
130 static int parsedirectory (const char *dir
, dki_t
**listp
, int sub_before
);
131 static void parsefile (const char *file
, dki_t
**listp
, int sub_before
);
132 static void usage (char *mesg
, zconf_t
*cp
);
134 static void setglobalflags (zconf_t
*config
)
136 recflag
= config
->recursive
;
137 ageflag
= config
->printage
;
138 timeflag
= config
->printtime
;
139 ljustflag
= config
->ljust
;
140 term
= config
->colorterm
;
141 if ( term
&& *term
== '\0' )
142 term
= getenv ("TERM");
145 int main (int argc
, char *argv
[])
152 const char *defconfname
= NULL
;
158 if ( (p
= strrchr (progname
, '/')) )
160 view
= getnameappendix (progname
, "zkt-ls");
162 defconfname
= getdefconfname (view
);
163 config
= loadconfig ("", (zconf_t
*)NULL
); /* load built in config */
164 if ( fileexist (defconfname
) ) /* load default config file */
165 config
= loadconfig (defconfname
, config
);
166 if ( config
== NULL
)
167 fatal ("Out of memory\n");
168 setglobalflags (config
);
173 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
174 while ( (c
= getopt_long (argc
, argv
, short_options
, long_options
, &opt_index
)) != -1 )
176 while ( (c
= getopt (argc
, argv
, short_options
)) != -1 )
181 #if defined(COLOR_MODE) && COLOR_MODE
182 case 'C': /* color mode on; optional with terminal name */
186 term
= getenv ("TERM");
191 subdomain_before_parent
= 0;
192 zskflag
= pathflag
= 0;
197 subdomain_before_parent
= 0;
198 zskflag
= pathflag
= 0;
208 case 'f': /* key lifetime */
209 lifetimeflag
= !lifetimeflag
;
211 case 'V': /* view name */
213 defconfname
= getdefconfname (view
);
214 if ( fileexist (defconfname
) ) /* load default config file */
215 config
= loadconfig (defconfname
, config
);
216 if ( config
== NULL
)
217 fatal ("Out of memory\n");
218 setglobalflags (config
);
221 config
= loadconfig (optarg
, config
);
222 setglobalflags (config
);
223 checkconfig (config
);
225 case 'O': /* read option from commandline */
226 config
= loadconfig_fromstr (optarg
, config
);
227 setglobalflags (config
);
228 checkconfig (config
);
230 case 'd': /* ignore directory arg */
233 case 'h': /* print no headline */
236 case 'k': /* ksk only */
239 case 'L': /* ljust */
240 ljustflag
= !ljustflag
;
242 case 'l': /* label list */
243 labellist
= prepstrlist (optarg
, LISTDELIM
);
244 if ( labellist
== NULL
)
245 fatal ("Out of memory\n");
247 case 'p': /* print path */
250 case 'r': /* switch recursive flag */
253 case 's': /* switch subdomain sorting flag */
254 subdomain_before_parent
= !subdomain_before_parent
;
257 timeflag
= !timeflag
;
259 case 'e': /* expire time */
260 exptimeflag
= !exptimeflag
;
262 case 'z': /* zsk only */
266 snprintf (str
, sizeof(str
), "option \"-%c\" requires an argument.\n",
271 if ( isprint (optopt
) )
272 snprintf (str
, sizeof(str
), "Unknown option \"-%c\".\n",
275 snprintf (str
, sizeof (str
), "Unknown option char \\x%x.\n",
284 if ( kskflag
== 0 && zskflag
== 0 )
285 kskflag
= zskflag
= 1;
287 tc_init (stdout
, term
);
291 if ( c
>= argc
) /* no args left */
292 file
= config
->zonedir
; /* use default directory */
296 if ( is_directory (file
) )
297 parsedirectory (file
, &data
, subdomain_before_parent
);
299 parsefile (file
, &data
, subdomain_before_parent
);
301 } while ( c
< argc
); /* for all arguments */
308 zkt_list_dnskeys (data
);
311 zkt_list_trustedkeys (data
);
314 zkt_list_managedkeys (data
);
317 zkt_list_keys (data
);
320 tc_end (stdout
, term
);
325 # define sopt_usage(mesg, value) fprintf (stderr, mesg, value)
326 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
327 # define lopt_usage(mesg, value) fprintf (stderr, mesg, value)
328 # define loptstr(lstr, sstr) lstr
330 # define lopt_usage(mesg, value)
331 # define loptstr(lstr, sstr) sstr
333 static void usage (char *mesg
, zconf_t
*cp
)
335 fprintf (stderr
, "Secure DNS Zone Key Tool %s\n", ZKT_VERSION
);
336 fprintf (stderr
, "\n");
338 fprintf (stderr
, "List keys in current or given directory (-r for recursive mode)\n");
339 sopt_usage ("\tusage: %s [-adefhkLprtzC] [-c config] [file|dir ...]\n", progname
);
340 fprintf (stderr
, "\n");
341 fprintf (stderr
, "List public part of keys in DNSKEY RR format\n");
342 sopt_usage ("\tusage: %s -K [-dhkrz] [-c config] [file|dir ...]\n", progname
);
343 lopt_usage ("\tusage: %s --list-dnskeys [-dhkzr] [-c config] [file|dir ...]\n", progname
);
344 fprintf (stderr
, "\n");
345 fprintf (stderr
, "List keys (output is suitable for trusted-keys section)\n");
346 sopt_usage ("\tusage: %s -T [-dhrz] [-c config] [file|dir ...]\n", progname
);
347 lopt_usage ("\tusage: %s --list-trustedkeys [-dhzr] [-c config] [file|dir ...]\n", progname
);
348 fprintf (stderr
, "\n");
349 fprintf (stderr
, "List managed keys (output is suitable for managed-keys section)\n");
350 sopt_usage ("\tusage: %s -M [-dhrz] [-c config] [file|dir ...]\n", progname
);
351 lopt_usage ("\tusage: %s --list-managedkeys [-dhzr] [-c config] [file|dir ...]\n", progname
);
352 fprintf (stderr
, "\n");
354 fprintf (stderr
, "General options \n");
355 fprintf (stderr
, "\t-c file%s", loptstr (", --config=file\n", ""));
356 fprintf (stderr
, "\t\t read config from <file> instead of %s\n", CONFIG_FILE
);
357 fprintf (stderr
, "\t-O optstr%s", loptstr (", --config-option=\"optstr\"\n", ""));
358 fprintf (stderr
, "\t\t read config options from commandline\n");
359 fprintf (stderr
, "\t-h%s\t no headline or trusted/managed-key section header/trailer in -T/-M mode\n", loptstr (", --nohead", "\t"));
360 fprintf (stderr
, "\t-d%s\t skip directory arguments\n", loptstr (", --directory", "\t"));
361 fprintf (stderr
, "\t-L%s\t print the domain name left justified (default: %s)\n", loptstr (", --leftjust", "\t"), ljustflag
? "on": "off");
362 fprintf (stderr
, "\t-l list%s", loptstr (", --label=\"list\"\n\t", ""));
363 fprintf (stderr
, "\t\t print out only zone keys from the given domain list\n");
364 fprintf (stderr
, "\t-C[term]%s", loptstr (", --color[=\"term\"]\n\t", ""));
365 fprintf (stderr
, "\t\t turn color mode on \n");
366 fprintf (stderr
, "\t-p%s\t show path of keyfile / create key in current directory\n", loptstr (", --path", "\t"));
367 fprintf (stderr
, "\t-r%s\t recursive mode on/off (default: %s)\n", loptstr(", --recursive", "\t"), recflag
? "on": "off");
368 fprintf (stderr
, "\t-s%s\t change sorting of subdomains\n", loptstr(", --subdomain", "\t"));
369 fprintf (stderr
, "\t-a%s\t print age of key (default: %s)\n", loptstr (", --age", "\t"), ageflag
? "on": "off");
370 fprintf (stderr
, "\t-t%s\t print key generation time (default: %s)\n", loptstr (", --time", "\t"),
371 timeflag
? "on": "off");
372 fprintf (stderr
, "\t-e%s\t print key expiration time\n", loptstr (", --expire", "\t"));
373 fprintf (stderr
, "\t-f%s\t print key lifetime\n", loptstr (", --lifetime", "\t"));
374 fprintf (stderr
, "\t-k%s\t key signing keys only\n", loptstr (", --ksk", "\t"));
375 fprintf (stderr
, "\t-z%s\t zone signing keys only\n", loptstr (", --zsk", "\t"));
377 fprintf (stderr
, "%s\n", mesg
);
381 static int parsedirectory (const char *dir
, dki_t
**listp
, int sub_before
)
385 struct dirent
*dentp
;
386 char path
[MAX_PATHSIZE
+1];
391 dbg_val ("directory: opendir(%s)\n", dir
);
392 if ( (dirp
= opendir (dir
)) == NULL
)
395 while ( (dentp
= readdir (dirp
)) != NULL
)
397 if ( is_dotfilename (dentp
->d_name
) )
400 dbg_val ("directory: check %s\n", dentp
->d_name
);
401 pathname (path
, sizeof (path
), dir
, dentp
->d_name
, NULL
);
402 if ( is_directory (path
) && recflag
)
404 dbg_val ("directory: recursive %s\n", path
);
405 parsedirectory (path
, listp
, sub_before
);
407 else if ( is_keyfilename (dentp
->d_name
) )
408 if ( (dkp
= dki_read (dir
, dentp
->d_name
)) )
410 // fprintf (stderr, "parsedir: tssearch (%d %s)\n", dkp, dkp->name);
411 #if defined (USE_TREE) && USE_TREE
412 dki_tadd (listp
, dkp
, sub_before
);
414 dki_add (listp
, dkp
);
422 static void parsefile (const char *file
, dki_t
**listp
, int sub_before
)
424 char path
[MAX_PATHSIZE
+1];
427 /* file arg contains path ? ... */
428 file
= splitpath (path
, sizeof (path
), file
); /* ... then split of */
430 if ( is_keyfilename (file
) ) /* plain file name looks like DNS key file ? */
432 if ( (dkp
= dki_read (path
, file
)) ) /* read DNS key file ... */
433 #if defined (USE_TREE) && USE_TREE
434 dki_tadd (listp
, dkp
, sub_before
); /* ... and add to tree */
436 dki_add (listp
, dkp
); /* ... and add to list */
439 error ("error parsing %s: (%s)\n", file
, dki_geterrstr());