1 /* $NetBSD: zkt-keyman.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) zkt-keyman.c (c) Jan 2005 - Apr 2010 Holger Zuleger hznet.de
7 ** ZKT key managing tool (formely knon as dnsses-zkt)
8 ** A wrapper command around the BIND dnssec-keygen utility
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
72 char *labellist
= NULL
;
85 static int dirflag
= 0;
86 static int recflag
= RECURSIVE
;
87 static char *kskdomain
= "";
88 static const char *view
= "";
90 # define short_options ":0:1:2:3:9A:C:D:P:S:R:h:ZV:F:c:O:krz"
91 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
92 static struct option long_options
[] = {
93 {"ksk-rollover", no_argument
, NULL
, '9'},
94 {"ksk-status", required_argument
, NULL
, '0'},
95 {"ksk-roll-status", required_argument
, NULL
, '0'},
96 {"ksk-newkey", required_argument
, NULL
, '1'},
97 {"ksk-publish", required_argument
, NULL
, '2'},
98 {"ksk-delkey", required_argument
, NULL
, '3'},
99 {"ksk-roll-phase1", required_argument
, NULL
, '1'},
100 {"ksk-roll-phase2", required_argument
, NULL
, '2'},
101 {"ksk-roll-phase3", required_argument
, NULL
, '3'},
102 {"ksk", no_argument
, NULL
, 'k'},
103 {"zsk", no_argument
, NULL
, 'z'},
104 {"recursive", no_argument
, NULL
, 'r'},
105 {"config", required_argument
, NULL
, 'c'},
106 {"option", required_argument
, NULL
, 'O'},
107 {"config-option", required_argument
, NULL
, 'O'},
108 {"published", required_argument
, NULL
, 'P'},
109 {"standby", required_argument
, NULL
, 'S'},
110 {"active", required_argument
, NULL
, 'A'},
111 {"depreciated", required_argument
, NULL
, 'D'},
112 {"create", required_argument
, NULL
, 'C'},
113 {"revoke", required_argument
, NULL
, 'R'},
114 {"remove", required_argument
, NULL
, 19 },
115 {"destroy", required_argument
, NULL
, 20 },
116 {"setlifetime", required_argument
, NULL
, 'F' },
117 {"view", required_argument
, NULL
, 'V' },
118 {"help", no_argument
, NULL
, 'h'},
123 static int parsedirectory (const char *dir
, dki_t
**listp
);
124 static void parsefile (const char *file
, dki_t
**listp
);
125 static void createkey (const char *keyname
, const dki_t
*list
, const zconf_t
*conf
);
126 static void ksk_roll (const char *keyname
, int phase
, const dki_t
*list
, const zconf_t
*conf
);
127 static int create_parent_file (const char *fname
, int phase
, int ttl
, const dki_t
*dkp
);
128 static void usage (char *mesg
, zconf_t
*cp
);
129 static const char *parsetag (const char *str
, int *tagp
);
131 static void setglobalflags (zconf_t
*config
)
133 recflag
= config
->recursive
;
136 int main (int argc
, char *argv
[])
144 const char *defconfname
= NULL
;
147 const char *keyname
= NULL
;
152 if ( (p
= strrchr (progname
, '/')) )
154 view
= getnameappendix (progname
, "dnssec-zkt");
156 defconfname
= getdefconfname (view
);
157 config
= loadconfig ("", (zconf_t
*)NULL
); /* load built in config */
158 if ( fileexist (defconfname
) ) /* load default config file */
159 config
= loadconfig (defconfname
, config
);
160 if ( config
== NULL
)
161 fatal ("Out of memory\n");
162 setglobalflags (config
);
167 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
168 while ( (c
= getopt_long (argc
, argv
, short_options
, long_options
, &opt_index
)) != -1 )
170 while ( (c
= getopt (argc
, argv
, short_options
)) != -1 )
175 case '9': /* ksk rollover help */
176 ksk_roll ("help", c
- '0', NULL
, NULL
);
178 case '1': /* ksk rollover: create new key */
179 case '2': /* ksk rollover: publish DS */
180 case '3': /* ksk rollover: delete old key */
181 case '0': /* ksk rollover: show current status */
184 usage ("ksk rollover requires an domain argument", config
);
185 kskdomain
= domain_canonicdup (optarg
);
193 pathflag
= !pathflag
;
203 if ( (keyname
= parsetag (optarg
, &searchtag
)) != NULL
)
204 keyname
= domain_canonicdup (keyname
);
207 case 'F': /* set key lifetime */
208 lifetime
= atoi (optarg
);
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 'k': /* ksk only */
236 case 'r': /* switch recursive flag */
239 case 'z': /* zsk only */
243 snprintf (str
, sizeof(str
), "option \"-%c\" requires an argument.\n",
248 if ( isprint (optopt
) )
249 snprintf (str
, sizeof(str
), "Unknown option \"-%c\".\n",
252 snprintf (str
, sizeof (str
), "Unknown option char \\x%x.\n",
261 if ( kskflag
== 0 && zskflag
== 0 )
262 kskflag
= zskflag
= 1;
266 if ( c
>= argc
) /* no args left */
267 file
= config
->zonedir
; /* use default directory */
271 if ( is_directory (file
) )
272 parsedirectory (file
, &data
);
274 parsefile (file
, &data
);
276 } while ( c
< argc
); /* for all arguments */
283 createkey (keyname
, data
, config
);
289 if ( (dkp
= (dki_t
*)zkt_search (data
, searchtag
, keyname
)) == NULL
)
290 fatal ("Key with tag %u not found\n", searchtag
);
291 else if ( dkp
== (void *) 01 )
292 fatal ("Key with tag %u found multiple times\n", searchtag
);
293 if ( (c
= dki_setstatus_preservetime (dkp
, action
)) != 0 )
294 fatal ("Couldn't change status of key %u: %d\n", searchtag
, c
);
296 case 19: /* remove (rename) key file */
297 if ( (dkp
= (dki_t
*)zkt_search (data
, searchtag
, keyname
)) == NULL
)
298 fatal ("Key with tag %u not found\n", searchtag
);
299 else if ( dkp
== (void *) 01 )
300 fatal ("Key with tag %u found multiple times\n", searchtag
);
303 case 20: /* destroy the key (remove the files!) */
304 if ( (dkp
= (dki_t
*)zkt_search (data
, searchtag
, keyname
)) == NULL
)
305 fatal ("Key with tag %u not found\n", searchtag
);
306 else if ( dkp
== (void *) 01 )
307 fatal ("Key with tag %u found multiple times\n", searchtag
);
311 if ( (dkp
= (dki_t
*)zkt_search (data
, searchtag
, keyname
)) == NULL
)
312 fatal ("Key with tag %u not found\n", searchtag
);
313 else if ( dkp
== (void *) 01 )
314 fatal ("Key with tag %u found multiple times\n", searchtag
);
315 if ( (c
= dki_setstatus (dkp
, action
)) != 0 )
316 fatal ("Couldn't change status of key %u: %d\n", searchtag
, c
);
318 case '1': /* ksk rollover new key */
319 case '2': /* ksk rollover publish DS */
320 case '3': /* ksk rollover delete old key */
321 case '0': /* ksk rollover status */
322 ksk_roll (kskdomain
, action
- '0', data
, config
);
325 zkt_setkeylifetime (data
);
328 zkt_list_keys (data
);
334 # define sopt_usage(mesg, value) fprintf (stderr, mesg, value)
335 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
336 # define lopt_usage(mesg, value) fprintf (stderr, mesg, value)
337 # define loptstr(lstr, sstr) lstr
339 # define lopt_usage(mesg, value)
340 # define loptstr(lstr, sstr) sstr
342 static void usage (char *mesg
, zconf_t
*cp
)
344 fprintf (stderr
, "DNS Zone Key Management Tool %s\n", ZKT_VERSION
);
345 fprintf (stderr
, "\n");
346 fprintf (stderr
, "Create a new key \n");
347 sopt_usage ("\tusage: %s -C <name> [-k] [-dpr] [-c config] [dir ...]\n", progname
);
348 lopt_usage ("\tusage: %s --create=<name> [-k] [-dpr] [-c config] [dir ...]\n", progname
);
349 fprintf (stderr
, "\t\tKSK (use -k): %s %d bits\n", dki_algo2str (cp
->k_algo
), cp
->k_bits
);
350 fprintf (stderr
, "\t\tZSK (default): %s %d bits\n", dki_algo2str (cp
->k_algo
), cp
->z_bits
);
351 fprintf (stderr
, "\n");
352 fprintf (stderr
, "Change key status of specified key to published, active or depreciated\n");
353 fprintf (stderr
, "\t(<keyspec> := tag | tag:name) \n");
354 sopt_usage ("\tusage: %s -P|-A|-D <keyspec> [-dr] [-c config] [dir ...]\n", progname
);
355 lopt_usage ("\tusage: %s --published=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
356 lopt_usage ("\tusage: %s --active=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
357 lopt_usage ("\tusage: %s --depreciated=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
358 fprintf (stderr
, "\n");
359 fprintf (stderr
, "Revoke specified key (<keyspec> := tag | tag:name) \n");
360 sopt_usage ("\tusage: %s -R <keyspec> [-dr] [-c config] [dir ...]\n", progname
);
361 lopt_usage ("\tusage: %s --revoke=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
362 fprintf (stderr
, "\n");
363 fprintf (stderr
, "Remove (rename) or destroy (delete) specified key (<keyspec> := tag | tag:name) \n");
364 lopt_usage ("\tusage: %s --remove=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
365 lopt_usage ("\tusage: %s --destroy=<keyspec> [-dr] [-c config] [dir ...]\n", progname
);
366 fprintf (stderr
, "\n");
367 fprintf (stderr
, "Initiate a semi-automated KSK rollover");
368 fprintf (stderr
, "('%s -9%s' prints out a brief description)\n", progname
, loptstr ("|--ksk-rollover", ""));
369 sopt_usage ("\tusage: %s {-1} do.ma.in.\n", progname
);
370 lopt_usage ("\tusage: %s {--ksk-roll-phase1|--ksk-newkey} do.ma.in.\n", progname
);
371 sopt_usage ("\tusage: %s {-2} do.ma.in.\n", progname
);
372 lopt_usage ("\tusage: %s {--ksk-roll-phase2|--ksk-publish} do.ma.in.\n", progname
);
373 sopt_usage ("\tusage: %s {-3} do.ma.in.\n", progname
);
374 lopt_usage ("\tusage: %s {--ksk-roll-phase3|--ksk-delkey} do.ma.in.\n", progname
);
375 sopt_usage ("\tusage: %s {-0} do.ma.in.\n", progname
);
376 lopt_usage ("\tusage: %s {--ksk-roll-status|--ksk-status} do.ma.in.\n", progname
);
377 fprintf (stderr
, "\n");
379 fprintf (stderr
, "\n");
380 fprintf (stderr
, "General options \n");
381 fprintf (stderr
, "\t-c file%s", loptstr (", --config=file\n", ""));
382 fprintf (stderr
, "\t\t read config from <file> instead of %s\n", CONFIG_FILE
);
383 fprintf (stderr
, "\t-O optstr%s", loptstr (", --config-option=\"optstr\"\n", ""));
384 fprintf (stderr
, "\t\t read config options from commandline\n");
385 fprintf (stderr
, "\t-d%s\t skip directory arguments\n", loptstr (", --directory", "\t"));
386 fprintf (stderr
, "\t-r%s\t recursive mode on/off (default: %s)\n", loptstr(", --recursive", "\t"), recflag
? "on": "off");
387 fprintf (stderr
, "\t-F days%s=days\t set key lifetime\n", loptstr (", --setlifetime", "\t"));
388 fprintf (stderr
, "\t-k%s\t key signing keys only\n", loptstr (", --ksk", "\t"));
389 fprintf (stderr
, "\t-z%s\t zone signing keys only\n", loptstr (", --zsk", "\t"));
391 fprintf (stderr
, "%s\n", mesg
);
395 static void createkey (const char *keyname
, const dki_t
*list
, const zconf_t
*conf
)
397 const char *dir
= "";
400 if ( keyname
== NULL
|| *keyname
== '\0' )
401 fatal ("Create key: no keyname!");
403 dbg_val2 ("createkey: keyname %s, pathflag = %d\n", keyname
, pathflag
);
404 /* search for already existent key to get the directory name */
405 if ( pathflag
&& (dkp
= (dki_t
*)zkt_search (list
, 0, keyname
)) != NULL
)
407 char path
[MAX_PATHSIZE
+1];
411 pathname (path
, sizeof (path
), dir
, LOCALCONF_FILE
, NULL
);
412 if ( fileexist (path
) ) /* load local config file */
414 dbg_val ("Load local config file \"%s\"\n", path
);
415 memcpy (&localconf
, conf
, sizeof (zconf_t
));
416 conf
= loadconfig (path
, &localconf
);
421 dkp
= dki_new (dir
, keyname
, DKI_ZSK
, conf
->k_algo
, conf
->z_bits
, conf
->z_random
, conf
->z_life
/ DAYSEC
);
423 dkp
= dki_new (dir
, keyname
, DKI_KSK
, conf
->k_algo
, conf
->k_bits
, conf
->k_random
, conf
->k_life
/ DAYSEC
);
425 fatal ("Can't create key %s: %s!\n", keyname
, dki_geterrstr ());
427 /* create a new key always in state published, which means "standby" for ksk */
428 dki_setstatus (dkp
, DKI_PUB
);
431 static int get_parent_phase (const char *file
)
436 if ( (fp
= fopen (file
, "r")) == NULL
)
440 if ( fscanf (fp
, "; KSK rollover phase%d", &phase
) != 1 )
447 static void ksk_roll (const char *keyname
, int phase
, const dki_t
*list
, const zconf_t
*conf
)
449 char path
[MAX_PATHSIZE
+1];
458 int parent_propagation
;
462 if ( phase
== 9 ) /* usage */
464 fprintf (stderr
, "A KSK rollover requires three consecutive steps:\n");
465 fprintf (stderr
, "\n");
466 fprintf (stderr
, "-1%s", loptstr ("|--ksk-roll-phase1 (--ksk-newkey)\n", ""));
467 fprintf (stderr
, "\t Create a new KSK.\n");
468 fprintf (stderr
, "\t This step also creates a parent-<domain> file which contains only\n");
469 fprintf (stderr
, "\t the _old_ key. This file will be copied in hierarchical mode\n");
470 fprintf (stderr
, "\t by dnssec-signer to the parent directory as keyset-<domain> file.\n");
471 fprintf (stderr
, "\t Wait until the new keyset is propagated, before going to the next step.\n");
472 fprintf (stderr
, "\n");
473 fprintf (stderr
, "-2%s", loptstr ("|--ksk-roll-phase2 (--ksk-publish)\n", ""));
474 fprintf (stderr
, "\t This step creates a parent-<domain> file with the _new_ key only.\n");
475 fprintf (stderr
, "\t Please send this file immediately to the parent (In hierarchical\n");
476 fprintf (stderr
, "\t mode this will be done automatically by the dnssec-signer command).\n");
477 fprintf (stderr
, "\t Then wait until the new DS is generated by the parent and propagated\n");
478 fprintf (stderr
, "\t to all the parent name server, plus the old DS TTL before going to step three.\n");
479 fprintf (stderr
, "\n");
480 fprintf (stderr
, "-3%s", loptstr ("|--ksk-roll-phase3 (--ksk-delkey)\n", ""));
481 fprintf (stderr
, "\t Remove (rename) the old KSK and the parent-<domain> file.\n");
482 fprintf (stderr
, "\t You have to manually delete the old KSK (look at file names beginning\n");
483 fprintf (stderr
, "\t with an lower 'k').\n");
484 fprintf (stderr
, "\n");
485 fprintf (stderr
, "-0%s", loptstr ("|--ksk-roll-stat (--ksk-status)\n", ""));
486 fprintf (stderr
, "\t Show the current KSK rollover state of a domain.\n");
488 fprintf (stderr
, "\n");
493 if ( keyname
== NULL
|| *keyname
== '\0' )
494 fatal ("ksk rollover: no domain!");
496 dbg_val2 ("ksk_roll: keyname %s, phase = %d\n", keyname
, phase
);
498 /* search for already existent key to get the directory name */
499 if ( (keylist
= (dki_t
*)zkt_search (list
, 0, keyname
)) == NULL
)
500 fatal ("ksk rollover: domain %s not found!\n", keyname
);
503 /* try to read local config file */
505 pathname (path
, sizeof (path
), dir
, LOCALCONF_FILE
, NULL
);
506 if ( fileexist (path
) ) /* load local config file */
508 dbg_val ("Load local config file \"%s\"\n", path
);
509 memcpy (&localconf
, conf
, sizeof (zconf_t
));
510 conf
= loadconfig (path
, &localconf
);
512 key_ttl
= conf
->key_ttl
;
514 /* check if parent-file already exist */
515 pathname (path
, sizeof (path
), dir
, "parent-", keyname
);
516 parent_phase
= parent_age
= 0;
517 if ( (parent_exist
= fileexist (path
)) != 0 )
519 parent_phase
= get_parent_phase (path
);
520 parent_age
= file_age (path
);
522 // parent_propagation = 2 * DAYSEC;
523 parent_propagation
= 5 * MINSEC
;
525 ksk
= 0; /* count active(!) key signing keys */
526 standby
= NULL
; /* find standby key if available */
527 for ( dkp
= keylist
; dkp
; dkp
= dkp
->next
)
528 if ( dki_isksk (dkp
) )
530 if ( dki_status (dkp
) == DKI_ACT
)
532 else if ( dki_status (dkp
) == DKI_PUB
)
538 case 0: /* print status (debug) */
539 fprintf (stdout
, "ksk_rollover:\n");
540 fprintf (stdout
, "\t domain = %s\n", keyname
);
541 fprintf (stdout
, "\t phase = %d\n", parent_phase
);
542 fprintf (stdout
, "\t parent_file %s %s\n", path
, parent_exist
? "exist": "not exist");
544 fprintf (stdout
, "\t age of parent_file %d %s\n", parent_age
, str_delspace (age2str (parent_age
)));
545 fprintf (stdout
, "\t # of active key signing keys %d\n", ksk
);
546 fprintf (stdout
, "\t parent_propagation %d %s\n", parent_propagation
, str_delspace (age2str (parent_propagation
)));
547 fprintf (stdout
, "\t keys ttl %d %s\n", key_ttl
, age2str (key_ttl
));
549 for ( dkp
= keylist
; dkp
; dkp
= dkp
->next
)
551 /* TODO: Nur zum testen */
552 dki_prt_dnskey (dkp
, stdout
);
556 if ( parent_exist
|| ksk
> 1 )
557 fatal ("Can\'t create new ksk because there is already an ksk rollover in progress\n");
559 fprintf (stdout
, "create new ksk \n");
560 dkp
= dki_new (dir
, keyname
, DKI_KSK
, conf
->k_algo
, conf
->k_bits
, conf
->k_random
, conf
->k_life
/ DAYSEC
);
562 fatal ("Can't create key %s: %s!\n", keyname
, dki_geterrstr ());
565 dki_setstatus (standby
, DKI_ACT
); /* activate standby key */
566 dki_setstatus (dkp
, DKI_PUB
); /* new key will be the new standby */
569 // dkp = keylist; /* use old key to create the parent file */
570 if ( (dkp
= (dki_t
*)dki_findalgo (keylist
, 1, conf
->k_algo
, 'a', 1)) == NULL
) /* find the oldest active ksk to create the parent file */
571 fatal ("ksk_rollover phase1: Couldn't find the old active key\n");
572 if ( !create_parent_file (path
, phase
, key_ttl
, dkp
) )
573 fatal ("Couldn't create parentfile %s\n", path
);
578 fatal ("Can\'t publish new key because no one exist\n");
580 fatal ("More than one KSK but no parent file found!\n");
581 if ( parent_phase
!= 1 )
582 fatal ("Parent file exists but is in wrong state (phase = %d)\n", parent_phase
);
583 if ( parent_age
< conf
->proptime
+ key_ttl
)
584 fatal ("ksk_rollover (phase2): you have to wait for the propagation of the new KSK (at least %dsec or %s)\n",
585 conf
->proptime
+ key_ttl
- parent_age
,
586 str_delspace (age2str (conf
->proptime
+ key_ttl
- parent_age
)));
588 fprintf (stdout
, "save new ksk in parent file\n");
589 dkp
= keylist
->next
; /* set dkp to new ksk */
590 if ( !create_parent_file (path
, phase
, key_ttl
, dkp
) )
591 fatal ("Couldn't create parentfile %s\n", path
);
594 if ( !parent_exist
|| ksk
< 2 )
595 fatal ("ksk-delkey only allowed after ksk-publish\n");
596 if ( parent_phase
!= 2 )
597 fatal ("Parent file exists but is in wrong state (phase = %d)\n", parent_phase
);
598 if ( parent_age
< parent_propagation
+ key_ttl
)
599 fatal ("ksk_rollover (phase3): you have to wait for DS propagation (at least %dsec or %s)\n",
600 parent_propagation
+ key_ttl
- parent_age
,
601 str_delspace (age2str (parent_propagation
+ key_ttl
- parent_age
)));
602 /* remove the parentfile */
603 fprintf (stdout
, "remove parentfile \n");
605 /* remove or rename the old key */
606 fprintf (stdout
, "old ksk renamed \n");
607 dkp
= keylist
; /* set dkp to old ksk */
610 default: assert (phase
== 1 || phase
== 2 || phase
== 3);
614 /*****************************************************************
615 ** create_parent_file ()
616 *****************************************************************/
617 static int create_parent_file (const char *fname
, int phase
, int ttl
, const dki_t
*dkp
)
621 assert ( fname
!= NULL
);
623 if ( dkp
== NULL
|| (phase
!= 1 && phase
!= 2) )
626 if ( (fp
= fopen (fname
, "w")) == NULL
)
627 fatal ("can\'t create new parentfile \"%s\"\n", fname
);
630 fprintf (fp
, "; KSK rollover phase1 (old key)\n");
632 fprintf (fp
, "; KSK rollover phase2 (new key)\n");
634 dki_prt_dnskeyttl (dkp
, fp
, ttl
);
640 static int parsedirectory (const char *dir
, dki_t
**listp
)
644 struct dirent
*dentp
;
645 char path
[MAX_PATHSIZE
+1];
650 dbg_val ("directory: opendir(%s)\n", dir
);
651 if ( (dirp
= opendir (dir
)) == NULL
)
654 while ( (dentp
= readdir (dirp
)) != NULL
)
656 if ( is_dotfilename (dentp
->d_name
) )
659 dbg_val ("directory: check %s\n", dentp
->d_name
);
660 pathname (path
, sizeof (path
), dir
, dentp
->d_name
, NULL
);
661 if ( is_directory (path
) && recflag
)
663 dbg_val ("directory: recursive %s\n", path
);
664 parsedirectory (path
, listp
);
666 else if ( is_keyfilename (dentp
->d_name
) )
667 if ( (dkp
= dki_read (dir
, dentp
->d_name
)) )
669 // fprintf (stderr, "parsedir: tssearch (%d %s)\n", dkp, dkp->name);
670 #if defined (USE_TREE) && USE_TREE
671 dki_tadd (listp
, dkp
, 1);
673 dki_add (listp
, dkp
);
681 static void parsefile (const char *file
, dki_t
**listp
)
683 char path
[MAX_PATHSIZE
+1];
686 /* file arg contains path ? ... */
687 file
= splitpath (path
, sizeof (path
), file
); /* ... then split of */
689 if ( is_keyfilename (file
) ) /* plain file name looks like DNS key file ? */
691 if ( (dkp
= dki_read (path
, file
)) ) /* read DNS key file ... */
692 #if defined (USE_TREE) && USE_TREE
693 dki_tadd (listp
, dkp
, 1); /* ... and add to tree */
695 dki_add (listp
, dkp
); /* ... and add to list */
698 error ("error parsing %s: (%s)\n", file
, dki_geterrstr());
702 static const char *parsetag (const char *str
, int *tagp
)
707 while ( isspace (*str
) ) /* skip leading ws */
711 if ( isdigit (*p
) ) /* keytag starts with digit */
713 sscanf (p
, "%u", tagp
); /* read keytag as number */
714 do /* eat up to the end of the number */
716 while ( isdigit (*p
) );
718 if ( *p
== ':' ) /* label follows ? */
719 return p
+1; /* return that */
721 return NULL
; /* no label */
723 return str
; /* return as label string if not a numeric keytag */