OpenDNSSEC-signer  1.3.14
signconf.c
Go to the documentation of this file.
1 /*
2  * $Id: signconf.c 7109 2013-04-22 09:52:44Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "parser/confparser.h"
35 #include "parser/signconfparser.h"
36 #include "scheduler/task.h"
37 #include "shared/duration.h"
38 #include "shared/file.h"
39 #include "shared/hsm.h"
40 #include "shared/log.h"
41 #include "signer/backup.h"
42 #include "shared/status.h"
43 #include "signer/keys.h"
44 #include "signer/signconf.h"
45 
46 static const char* sc_str = "signconf";
47 
48 
55 {
56  signconf_type* sc;
57  allocator_type* allocator = allocator_create(malloc, free);
58  if (!allocator) {
59  ods_log_error("[%s] unable to create: create allocator failed",
60  sc_str);
61  return NULL;
62  }
63  ods_log_assert(allocator);
64 
65  sc = (signconf_type*) allocator_alloc(allocator, sizeof(signconf_type));
66  if (!sc) {
67  ods_log_error("[%s] unable to create: allocator failed", sc_str);
68  allocator_cleanup(allocator);
69  return NULL;
70  }
71  ods_log_assert(sc);
72  sc->allocator = allocator;
73  sc->filename = NULL;
74  /* Signatures */
75  sc->sig_resign_interval = NULL;
76  sc->sig_refresh_interval = NULL;
77  sc->sig_validity_default = NULL;
78  sc->sig_validity_denial = NULL;
79  sc->sig_jitter = NULL;
80  sc->sig_inception_offset = NULL;
81  /* Denial of existence */
82  sc->nsec_type = 0;
83  sc->nsec3_optout = 0;
84  sc->nsec3_algo = 0;
85  sc->nsec3_iterations = 0;
86  sc->nsec3_salt = NULL;
87  /* Keys */
88  sc->dnskey_ttl = NULL;
89  sc->keys = NULL;
90  /* Source of authority */
91  sc->soa_ttl = NULL;
92  sc->soa_min = NULL;
93  sc->soa_serial = NULL;
94  /* Other useful information */
95  sc->last_modified = 0;
96  sc->audit = 0;
97  return sc;
98 }
99 
100 
105 static ods_status
106 signconf_read(signconf_type* signconf, const char* scfile)
107 {
108  const char* rngfile = ODS_SE_RNGDIR "/signconf.rng";
109  ods_status status = ODS_STATUS_OK;
110  FILE* fd = NULL;
111 
112  ods_log_assert(scfile);
113  ods_log_assert(signconf);
114  ods_log_debug("[%s] read file %s", sc_str, scfile);
115 
116  status = parse_file_check(scfile, rngfile);
117  if (status != ODS_STATUS_OK) {
118  ods_log_error("[%s] unable to parse file %s: %s", sc_str, scfile,
119  ods_status2str(status));
120  return status;
121  }
122 
123  fd = ods_fopen(scfile, NULL, "r");
124  if (fd) {
125  signconf->filename = allocator_strdup(signconf->allocator, scfile);
130  signconf->sig_jitter = parse_sc_sig_jitter(scfile);
132  signconf->nsec_type = parse_sc_nsec_type(scfile);
133  if (signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
134  signconf->nsec3_optout = parse_sc_nsec3_optout(scfile);
135  signconf->nsec3_algo = parse_sc_nsec3_algorithm(scfile);
136  signconf->nsec3_iterations = parse_sc_nsec3_iterations(scfile);
137  signconf->nsec3_salt = parse_sc_nsec3_salt(signconf->allocator,
138  scfile);
139  }
140  signconf->keys = parse_sc_keys(signconf->allocator, scfile);
141  signconf->dnskey_ttl = parse_sc_dnskey_ttl(scfile);
142  signconf->soa_ttl = parse_sc_soa_ttl(scfile);
143  signconf->soa_min = parse_sc_soa_min(scfile);
144  signconf->soa_serial = parse_sc_soa_serial(signconf->allocator,
145  scfile);
146  signconf->audit = parse_sc_audit(scfile);
147  ods_fclose(fd);
148  return ODS_STATUS_OK;
149  }
150  ods_log_error("[%s] unable to read signconf file %s", sc_str, scfile);
151  return ODS_STATUS_ERR;
152 }
153 
154 
160 signconf_update(signconf_type** signconf, const char* scfile,
161  time_t last_modified)
162 {
163  signconf_type* new_sc = NULL;
164  time_t st_mtime = 0;
165  ods_status status = ODS_STATUS_OK;
166 
167  if (!signconf) {
168  ods_log_error("[%s] no signconf storage", sc_str);
169  return ODS_STATUS_UNCHANGED;
170  }
171  ods_log_assert(signconf);
172  if (!scfile) {
173  ods_log_error("[%s] no signconf filename", sc_str);
174  return ODS_STATUS_UNCHANGED;
175  }
176  ods_log_assert(scfile);
177 
178  /* is the file updated? */
179  st_mtime = ods_file_lastmodified(scfile);
180  if (st_mtime <= last_modified) {
181  ods_log_deeebug("[%s] file %s not modified since (file %u, "
182  "mem %u)", sc_str, scfile, (unsigned) st_mtime,
183  (unsigned) last_modified);
184  return ODS_STATUS_UNCHANGED;
185  }
186 
187  new_sc = signconf_create();
188  if (!new_sc) {
189  ods_log_error("[%s] error creating new signconf", sc_str);
190  return ODS_STATUS_ERR;
191  }
192 
193  status = signconf_read(new_sc, scfile);
194  if (status == ODS_STATUS_OK) {
195  new_sc->last_modified = st_mtime;
196  if (signconf_check(new_sc) != ODS_STATUS_OK) {
197  ods_log_error("[%s] signconf %s has errors", sc_str, scfile);
198  signconf_cleanup(new_sc);
199  return ODS_STATUS_CFG_ERR;
200  }
201  *signconf = new_sc;
202  } else {
203  ods_log_error("[%s] unable to read file %s: %s", sc_str, scfile,
204  ods_status2str(status));
205  signconf_cleanup(new_sc);
206  }
207  return status;
208 }
209 
210 
216 signconf_recover_from_backup(const char* filename)
217 {
218  signconf_type* signconf = NULL;
219  const char* zonename = NULL;
220  FILE* scfd = NULL;
221 
222  scfd = ods_fopen(filename, NULL, "r");
223  if (scfd) {
224  signconf = signconf_create();
225 
226  if (!backup_read_check_str(scfd, ODS_SE_FILE_MAGIC) ||
227  !backup_read_check_str(scfd, ";name:") ||
228  !backup_read_str(scfd, &zonename) ||
229  !backup_read_check_str(scfd, ";filename:") ||
230  !backup_read_str(scfd, &signconf->filename) ||
231  !backup_read_check_str(scfd, ";last_modified:") ||
232  !backup_read_time_t(scfd, &signconf->last_modified) ||
233  !backup_read_check_str(scfd, ";sig_resign_interval:") ||
234  !backup_read_duration(scfd, &signconf->sig_resign_interval) ||
235  !backup_read_check_str(scfd, ";sig_refresh_interval:") ||
236  !backup_read_duration(scfd, &signconf->sig_refresh_interval) ||
237  !backup_read_check_str(scfd, ";sig_validity_default:") ||
238  !backup_read_duration(scfd, &signconf->sig_validity_default) ||
239  !backup_read_check_str(scfd, ";sig_validity_denial:") ||
240  !backup_read_duration(scfd, &signconf->sig_validity_denial) ||
241  !backup_read_check_str(scfd, ";sig_jitter:") ||
242  !backup_read_duration(scfd, &signconf->sig_jitter) ||
243  !backup_read_check_str(scfd, ";sig_inception_offset:") ||
244  !backup_read_duration(scfd, &signconf->sig_inception_offset) ||
245  !backup_read_check_str(scfd, ";nsec_type:") ||
246  !backup_read_rr_type(scfd, &signconf->nsec_type) ||
247  !backup_read_check_str(scfd, ";dnskey_ttl:") ||
248  !backup_read_duration(scfd, &signconf->dnskey_ttl) ||
249  !backup_read_check_str(scfd, ";soa_ttl:") ||
250  !backup_read_duration(scfd, &signconf->soa_ttl) ||
251  !backup_read_check_str(scfd, ";soa_min:") ||
252  !backup_read_duration(scfd, &signconf->soa_min) ||
253  !backup_read_check_str(scfd, ";soa_serial:") ||
254  !backup_read_str(scfd, &signconf->soa_serial) ||
255  !backup_read_check_str(scfd, ";audit:") ||
256  !backup_read_int(scfd, &signconf->audit) ||
257  !backup_read_check_str(scfd, ODS_SE_FILE_MAGIC))
258  {
259  ods_log_error("[%s] unable to recover signconf backup file %s: corrupt "
260  "backup file ", sc_str, filename?filename:"(null)");
261  signconf_cleanup(signconf);
262  signconf = NULL;
263  }
264 
265  if (zonename) {
266  free((void*) zonename);
267  }
268  ods_fclose(scfd);
269  return signconf;
270  }
271 
272  ods_log_debug("[%s] unable to recover signconf backup file %s", sc_str,
273  filename?filename:"(null)");
274  return NULL;
275 }
276 
277 
282 static void
283 signconf_backup_duration(FILE* fd, const char* opt, duration_type* duration)
284 {
285  char* str = duration2string(duration);
286  fprintf(fd, "%s %s ", opt, str);
287  free((void*) str);
288  return;
289 }
290 
291 
292 
297 void
299 {
300  if (!fd || !sc) {
301  return;
302  }
303  ods_log_assert(fd);
304  ods_log_assert(sc);
305 
306  fprintf(fd, ";;Signconf: lastmod %u ", (unsigned) sc->last_modified);
307  signconf_backup_duration(fd, "resign", sc->sig_resign_interval);
308  signconf_backup_duration(fd, "refresh", sc->sig_refresh_interval);
309  signconf_backup_duration(fd, "valid", sc->sig_validity_default);
310  signconf_backup_duration(fd, "denial", sc->sig_validity_denial);
311  signconf_backup_duration(fd, "jitter", sc->sig_jitter);
312  signconf_backup_duration(fd, "offset", sc->sig_inception_offset);
313  fprintf(fd, "nsec %u ", (unsigned) sc->nsec_type);
314  signconf_backup_duration(fd, "dnskeyttl", sc->dnskey_ttl);
315  signconf_backup_duration(fd, "soattl", sc->soa_ttl);
316  signconf_backup_duration(fd, "soamin", sc->soa_min);
317  fprintf(fd, "serial %s ", sc->soa_serial?sc->soa_serial:"(null)");
318  fprintf(fd, "audit %i\n", sc->audit);
319  return;
320 }
321 
322 
327 static int
328 signconf_soa_serial_check(const char* serial) {
329  if (!serial) {
330  return 1;
331  }
332 
333  if (strlen(serial) == 4 && strncmp(serial, "keep", 4) == 0) {
334  return 0;
335  }
336  if (strlen(serial) == 7 && strncmp(serial, "counter", 7) == 0) {
337  return 0;
338  }
339  if (strlen(serial) == 8 && strncmp(serial, "unixtime", 8) == 0) {
340  return 0;
341  }
342  if (strlen(serial) == 11 && strncmp(serial, "datecounter", 11) == 0) {
343  return 0;
344  }
345  return 1;
346 }
347 
354 {
355  ods_status status = ODS_STATUS_OK;
356 
357  if (!sc->sig_resign_interval) {
358  ods_log_error("[%s] check failed: no signature resign interval found",
359  sc_str);
360  status = ODS_STATUS_CFG_ERR;
361  }
362  if (!sc->sig_refresh_interval) {
363  ods_log_error("[%s] check failed: no signature resign interval found",
364  sc_str);
365  status = ODS_STATUS_CFG_ERR;
366  }
367  if (!sc->sig_validity_default) {
368  ods_log_error("[%s] check failed: no signature default validity found",
369  sc_str);
370  status = ODS_STATUS_CFG_ERR;
371  }
372  if (!sc->sig_validity_denial) {
373  ods_log_error("[%s] check failed: no signature denial validity found",
374  sc_str);
375  status = ODS_STATUS_CFG_ERR;
376  }
377  if (!sc->sig_jitter) {
378  ods_log_error("[%s] check failed: no signature jitter found", sc_str);
379  status = ODS_STATUS_CFG_ERR;
380  }
381  if (!sc->sig_inception_offset) {
382  ods_log_error("[%s] check failed: no signature inception offset found",
383  sc_str);
384  status = ODS_STATUS_CFG_ERR;
385  }
386  if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
387  if (sc->nsec3_algo == 0) {
388  ods_log_error("[%s] check failed: no nsec3 algorithm found",
389  sc_str);
390  status = ODS_STATUS_CFG_ERR;
391  }
392  /* iterations */
393  /* salt */
394  /* optout */
395  } else if (sc->nsec_type != LDNS_RR_TYPE_NSEC) {
396  ods_log_error("[%s] check failed: wrong nsec type %i", sc_str,
397  sc->nsec_type);
398  status = ODS_STATUS_CFG_ERR;
399  }
400  if (!sc->keys || sc->keys->count == 0) {
401  ods_log_error("[%s] check failed: no keys found", sc_str);
402  status = ODS_STATUS_CFG_ERR;
403  }
404  if (!sc->dnskey_ttl) {
405  ods_log_error("[%s] check failed: no dnskey ttl found", sc_str);
406  status = ODS_STATUS_CFG_ERR;
407  }
408  if (!sc->soa_ttl) {
409  ods_log_error("[%s] check failed: no soa ttl found", sc_str);
410  status = ODS_STATUS_CFG_ERR;
411  }
412  if (!sc->soa_min) {
413  ods_log_error("[%s] check failed: no soa minimum found", sc_str);
414  status = ODS_STATUS_CFG_ERR;
415  }
416  if (!sc->soa_serial) {
417  ods_log_error("[%s] check failed: no soa serial type found", sc_str);
418  status = ODS_STATUS_CFG_ERR;
419  } else if (signconf_soa_serial_check(sc->soa_serial) != 0) {
420  ods_log_error("[%s] check failed: wrong soa serial type %s", sc_str,
421  sc->soa_serial);
422  status = ODS_STATUS_CFG_ERR;
423  }
424 
425  return status;
426 }
427 
428 
433 task_id
435 {
436  task_id new_task = TASK_NONE;
437  if (!a || !b) {
438  return TASK_NONE;
439  }
440  ods_log_assert(a);
441  ods_log_assert(b);
442 
443  if (duration_compare(a->soa_min, b->soa_min)) {
444  new_task = TASK_NSECIFY;
445  } else if (a->nsec_type != b->nsec_type) {
446  new_task = TASK_NSECIFY;
447  } else if (a->nsec_type == LDNS_RR_TYPE_NSEC3) {
448  if ((ods_strcmp(a->nsec3_salt, b->nsec3_salt) != 0) ||
449  (a->nsec3_algo != b->nsec3_algo) ||
450  (a->nsec3_iterations != b->nsec3_iterations) ||
451  (a->nsec3_optout != b->nsec3_optout)) {
452 
453  new_task = TASK_NSECIFY;
454  }
455  }
456  return new_task;
457 }
458 
459 
464 task_id
466 {
467  task_id new_task = TASK_NONE;
468  ods_status status = ODS_STATUS_OK;
469  key_type* walk = NULL;
470  key_type* ka = NULL;
471  key_type* kb = NULL;
472  int remove = 0;
473  int copy = 0;
474 
475  if (!a || !b) {
476  return TASK_NONE;
477  }
478  ods_log_assert(a);
479  ods_log_assert(b);
480 
481  /* keys deleted? */
482  if (a->keys) {
483  walk = a->keys->first_key;
484  }
485  while (walk && walk->locator) {
486  remove = 0;
487  copy = 0;
488 
489  kb = keylist_lookup(b->keys, walk->locator);
490  if (!kb) {
491  remove = 1; /* [DEL] key removed from signconf */
492  } else {
493  if (duration_compare(a->dnskey_ttl, b->dnskey_ttl) != 0) {
494  remove = 1; /* [DEL] consider to be different key */
495  } else if (walk->flags != kb->flags) {
496  remove = 1; /* [DEL] consider to be different key */
497  } else if (walk->algorithm != kb->algorithm) {
498  remove = 1; /* [DEL] consider to be different key */
499  } else if (walk->publish != kb->publish) {
500  if (walk->publish) {
501  remove = 1; /* [DEL] withdraw dnskey from zone */
502  } else {
503  new_task = TASK_READ; /* [ADD] introduce key to zone */
504  }
505  } else if (walk->ksk != kb->ksk) {
506  copy = 1; /* [UNCHANGED] same key, different role */
507  } else if (walk->zsk != kb->zsk) {
508  copy = 1; /* [UNCHANGED] same key, different role */
509  } else {
510  /* [UNCHANGED] identical key credentials */
511  copy = 1;
512  }
513  }
514 
515  if (remove) {
516  new_task = TASK_READ;
517  if (del && walk->dnskey) {
518  if (!ldns_rr_list_push_rr(del, walk->dnskey)) {
519  ods_log_error("[%s] del key failed", sc_str);
520  new_task = TASK_SIGNCONF;
521  break;
522  }
523  }
524  } else if (copy) {
525  if (walk->dnskey && !kb->dnskey) {
526  kb->dnskey = walk->dnskey;
527  kb->hsmkey = walk->hsmkey;
528  status = lhsm_get_key(NULL, ldns_rr_owner(walk->dnskey), kb);
529  walk->hsmkey = NULL;
530  walk->dnskey = NULL;
531  }
532  if (status != ODS_STATUS_OK) {
533  ods_log_error("[%s] copy key failed", sc_str);
534  new_task = TASK_SIGNCONF;
535  break;
536  }
537  }
538  walk = walk->next;
539  }
540 
541  if (new_task == TASK_NONE) {
542  /* no error and no keys were deleted, perhaps keys were added */
543  walk = NULL;
544  if (b->keys) {
545  walk = b->keys->first_key;
546  }
547  while (walk) {
548  ka = keylist_lookup(a->keys, walk->locator);
549  if (!ka) {
550  new_task = TASK_READ; /* [ADD] key added to signconf */
551  break;
552  }
557  walk = walk->next;
558  }
559  }
560  return new_task;
561 }
562 
563 
568 task_id
570 {
571  task_id new_task = TASK_NONE;
572  task_id tmp_task = TASK_NONE;
573 
574  new_task = signconf_compare_denial(a, b);
575  tmp_task = signconf_compare_keys(a, b, NULL);
576  if (tmp_task != TASK_NONE) {
577  new_task = tmp_task;
578  }
579  /* not like python: reschedule if resign/refresh differs */
580  /* this needs review, tasks correct on signconf changes? */
581  return new_task;
582 }
583 
584 
589 void
591 {
592  allocator_type* allocator;
593  if (!sc) {
594  return;
595  }
605  keylist_cleanup(sc->keys);
606 
607  allocator = sc->allocator;
608  allocator_deallocate(allocator, (void*) sc->filename);
609  allocator_deallocate(allocator, (void*) sc->nsec3_salt);
610  allocator_deallocate(allocator, (void*) sc->soa_serial);
611  allocator_deallocate(allocator, (void*) sc);
612  allocator_cleanup(allocator);
613  return;
614 }
615 
616 
621 void
622 signconf_print(FILE* out, signconf_type* sc, const char* name)
623 {
624  char* s = NULL;
625 
626  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
627 
628  if (sc) {
629  fprintf(out, "<SignerConfiguration>\n");
630  fprintf(out, "\t<Zone name=\"%s\">\n", name?name:"(null)");
631 
632  /* Signatures */
633  fprintf(out, "\t\t<Signatures>\n");
635  fprintf(out, "\t\t\t<Resign>%s</Resign>\n", s?s:"(null)");
636  free((void*)s);
637 
639  fprintf(out, "\t\t\t<Refresh>%s</Refresh>\n", s?s:"(null)");
640  free((void*)s);
641 
642  fprintf(out, "\t\t\t<Validity>\n");
643 
645  fprintf(out, "\t\t\t\t<Default>%s</Default>\n", s?s:"(null)");
646  free((void*)s);
647 
649  fprintf(out, "\t\t\t\t<Denial>%s</Denial>\n", s?s:"(null)");
650  free((void*)s);
651 
652  fprintf(out, "\t\t\t</Validity>\n");
653 
654  s = duration2string(sc->sig_jitter);
655  fprintf(out, "\t\t\t<Jitter>%s</Jitter>\n", s?s:"(null)");
656  free((void*)s);
657 
659  fprintf(out, "\t\t\t<InceptionOffset>%s</InceptionOffset>\n",
660  s?s:"(null)");
661  free((void*)s);
662 
663  fprintf(out, "\t\t</Signatures>\n");
664  fprintf(out, "\n");
665 
666  /* Denial */
667  fprintf(out, "\t\t<Denial>\n");
668  if (sc->nsec_type == LDNS_RR_TYPE_NSEC) {
669  fprintf(out, "\t\t\t<NSEC />\n");
670  } else if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
671  fprintf(out, "\t\t\t<NSEC3>\n");
672  if (sc->nsec3_optout) {
673  fprintf(out, "\t\t\t\t<OptOut />\n");
674  }
675  fprintf(out, "\t\t\t\t<Hash>\n");
676  fprintf(out, "\t\t\t\t\t<Algorithm>%i</Algorithm>\n",
677  sc->nsec3_algo);
678  fprintf(out, "\t\t\t\t\t<Iterations>%i</Iterations>\n",
679  sc->nsec3_iterations);
680  fprintf(out, "\t\t\t\t\t<Salt>%s</Salt>\n",
681  sc->nsec3_salt?sc->nsec3_salt:"(null)");
682  fprintf(out, "\t\t\t\t</Hash>\n");
683  fprintf(out, "\t\t\t</NSEC3>\n");
684  }
685  fprintf(out, "\t\t</Denial>\n");
686  fprintf(out, "\n");
687 
688  /* Keys */
689  fprintf(out, "\t\t<Keys>\n");
690  s = duration2string(sc->dnskey_ttl);
691  fprintf(out, "\t\t\t<TTL>%s</TTL>\n", s?s:"(null)");
692  free((void*)s);
693  fprintf(out, "\n");
694  keylist_print(out, sc->keys);
695  fprintf(out, "\t\t</Keys>\n");
696  fprintf(out, "\n");
697 
698  /* SOA */
699  fprintf(out, "\t\t<SOA>\n");
700  s = duration2string(sc->soa_ttl);
701  fprintf(out, "\t\t\t<TTL>%s</TTL>\n", s?s:"(null)");
702  free((void*)s);
703 
704  s = duration2string(sc->soa_min);
705  fprintf(out, "\t\t\t<Minimum>%s</Minimum>\n", s?s:"(null)");
706  free((void*)s);
707 
708  fprintf(out, "\t\t\t<Serial>%s</Serial>\n",
709  sc->soa_serial?sc->soa_serial:"(null)");
710  fprintf(out, "\t\t</SOA>\n");
711  fprintf(out, "\n");
712 
713  /* Audit */
714  if (sc->audit) {
715  fprintf(out, "\t\t<Audit />\n");
716  fprintf(out, "\n");
717  }
718 
719  fprintf(out, "\t</Zone>\n");
720  fprintf(out, "</SignerConfiguration>\n");
721  }
722  return;
723 }
724 
725 
730 void
731 signconf_log(signconf_type* sc, const char* name)
732 {
733  char* resign = NULL;
734  char* refresh = NULL;
735  char* validity = NULL;
736  char* denial = NULL;
737  char* jitter = NULL;
738  char* offset = NULL;
739  char* dnskeyttl = NULL;
740  char* soattl = NULL;
741  char* soamin = NULL;
742 
743  if (sc) {
744  resign = duration2string(sc->sig_resign_interval);
745  refresh = duration2string(sc->sig_refresh_interval);
746  validity = duration2string(sc->sig_validity_default);
747  denial = duration2string(sc->sig_validity_denial);
748  jitter = duration2string(sc->sig_jitter);
750  dnskeyttl = duration2string(sc->dnskey_ttl);
751  soattl = duration2string(sc->soa_ttl);
752  soamin = duration2string(sc->soa_min);
753 
754  ods_log_info("[%s] zone %s signconf: RESIGN[%s] REFRESH[%s] "
755  "VALIDITY[%s] DENIAL[%s] JITTER[%s] OFFSET[%s] NSEC[%i] "
756  "DNSKEYTTL[%s] SOATTL[%s] MINIMUM[%s] SERIAL[%s] AUDIT[%i]",
757  sc_str, name?name:"(null)", resign, refresh, validity, denial,
758  jitter, offset, (int) sc->nsec_type, dnskeyttl, soattl,
759  soamin, sc->soa_serial?sc->soa_serial:"(null)",
760  (int) sc->audit);
761 
762  if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
763  ods_log_info("[%s] zone %s nsec3: OPTOUT[%i] ALGORITHM[%u] "
764  "ITERATIONS[%u] SALT[%s]", sc_str, name, sc->nsec3_optout,
765  sc->nsec3_algo, sc->nsec3_iterations,
766  sc->nsec3_salt?sc->nsec3_salt:"(null)");
767  }
768 
769  /* Keys */
770  keylist_log(sc->keys, name);
771 
772  free((void*)resign);
773  free((void*)refresh);
774  free((void*)validity);
775  free((void*)denial);
776  free((void*)jitter);
777  free((void*)offset);
778  free((void*)dnskeyttl);
779  free((void*)soattl);
780  free((void*)soamin);
781  }
782  return;
783 }