OpenDNSSEC-signer  1.3.8
/build/buildd/opendnssec-1.3.8/signer/src/signer/signconf.c
Go to the documentation of this file.
00001 /*
00002  * $Id: signconf.c 6272 2012-04-20 10:25:47Z matthijs $
00003  *
00004  * Copyright (c) 2009 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "parser/confparser.h"
00035 #include "parser/signconfparser.h"
00036 #include "scheduler/task.h"
00037 #include "shared/duration.h"
00038 #include "shared/file.h"
00039 #include "shared/hsm.h"
00040 #include "shared/log.h"
00041 #include "signer/backup.h"
00042 #include "shared/status.h"
00043 #include "signer/keys.h"
00044 #include "signer/signconf.h"
00045 
00046 static const char* sc_str = "signconf";
00047 
00048 
00053 signconf_type*
00054 signconf_create(void)
00055 {
00056     signconf_type* sc;
00057     allocator_type* allocator = allocator_create(malloc, free);
00058     if (!allocator) {
00059         ods_log_error("[%s] unable to create: create allocator failed",
00060             sc_str);
00061         return NULL;
00062     }
00063     ods_log_assert(allocator);
00064 
00065     sc = (signconf_type*) allocator_alloc(allocator, sizeof(signconf_type));
00066     if (!sc) {
00067         ods_log_error("[%s] unable to create: allocator failed", sc_str);
00068         allocator_cleanup(allocator);
00069         return NULL;
00070     }
00071     ods_log_assert(sc);
00072     sc->allocator = allocator;
00073     sc->filename = NULL;
00074     /* Signatures */
00075     sc->sig_resign_interval = NULL;
00076     sc->sig_refresh_interval = NULL;
00077     sc->sig_validity_default = NULL;
00078     sc->sig_validity_denial = NULL;
00079     sc->sig_jitter = NULL;
00080     sc->sig_inception_offset = NULL;
00081     /* Denial of existence */
00082     sc->nsec_type = 0;
00083     sc->nsec3_optout = 0;
00084     sc->nsec3_algo = 0;
00085     sc->nsec3_iterations = 0;
00086     sc->nsec3_salt = NULL;
00087     /* Keys */
00088     sc->dnskey_ttl = NULL;
00089     sc->keys = NULL;
00090     /* Source of authority */
00091     sc->soa_ttl = NULL;
00092     sc->soa_min = NULL;
00093     sc->soa_serial = NULL;
00094     /* Other useful information */
00095     sc->last_modified = 0;
00096     sc->audit = 0;
00097     return sc;
00098 }
00099 
00100 
00105 static ods_status
00106 signconf_read(signconf_type* signconf, const char* scfile)
00107 {
00108     const char* rngfile = ODS_SE_RNGDIR "/signconf.rng";
00109     ods_status status = ODS_STATUS_OK;
00110     FILE* fd = NULL;
00111 
00112     ods_log_assert(scfile);
00113     ods_log_assert(signconf);
00114     ods_log_debug("[%s] read file %s", sc_str, scfile);
00115 
00116     status = parse_file_check(scfile, rngfile);
00117     if (status != ODS_STATUS_OK) {
00118         ods_log_error("[%s] unable to parse file %s: %s", sc_str, scfile,
00119             ods_status2str(status));
00120         return status;
00121     }
00122 
00123     fd = ods_fopen(scfile, NULL, "r");
00124     if (fd) {
00125         signconf->filename = allocator_strdup(signconf->allocator, scfile);
00126         signconf->sig_resign_interval = parse_sc_sig_resign_interval(scfile);
00127         signconf->sig_refresh_interval = parse_sc_sig_refresh_interval(scfile);
00128         signconf->sig_validity_default = parse_sc_sig_validity_default(scfile);
00129         signconf->sig_validity_denial = parse_sc_sig_validity_denial(scfile);
00130         signconf->sig_jitter = parse_sc_sig_jitter(scfile);
00131         signconf->sig_inception_offset = parse_sc_sig_inception_offset(scfile);
00132         signconf->nsec_type = parse_sc_nsec_type(scfile);
00133         if (signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
00134             signconf->nsec3_optout = parse_sc_nsec3_optout(scfile);
00135             signconf->nsec3_algo = parse_sc_nsec3_algorithm(scfile);
00136             signconf->nsec3_iterations = parse_sc_nsec3_iterations(scfile);
00137             signconf->nsec3_salt = parse_sc_nsec3_salt(signconf->allocator,
00138                 scfile);
00139         }
00140         signconf->keys = parse_sc_keys(signconf->allocator, scfile);
00141         signconf->dnskey_ttl = parse_sc_dnskey_ttl(scfile);
00142         signconf->soa_ttl = parse_sc_soa_ttl(scfile);
00143         signconf->soa_min = parse_sc_soa_min(scfile);
00144         signconf->soa_serial = parse_sc_soa_serial(signconf->allocator,
00145             scfile);
00146         signconf->audit = parse_sc_audit(scfile);
00147         ods_fclose(fd);
00148         return ODS_STATUS_OK;
00149     }
00150     ods_log_error("[%s] unable to read signconf file %s", sc_str, scfile);
00151     return ODS_STATUS_ERR;
00152 }
00153 
00154 
00159 ods_status
00160 signconf_update(signconf_type** signconf, const char* scfile,
00161     time_t last_modified)
00162 {
00163     signconf_type* new_sc = NULL;
00164     time_t st_mtime = 0;
00165     ods_status status = ODS_STATUS_OK;
00166 
00167     if (!signconf) {
00168         ods_log_error("[%s] no signconf storage", sc_str);
00169         return ODS_STATUS_UNCHANGED;
00170     }
00171     ods_log_assert(signconf);
00172     if (!scfile) {
00173         ods_log_error("[%s] no signconf filename", sc_str);
00174         return ODS_STATUS_UNCHANGED;
00175     }
00176     ods_log_assert(scfile);
00177 
00178     /* is the file updated? */
00179     st_mtime = ods_file_lastmodified(scfile);
00180     if (st_mtime <= last_modified) {
00181         ods_log_deeebug("[%s] file %s not modified since (file %u, "
00182             "mem %u)", sc_str, (unsigned) st_mtime,
00183             (unsigned) last_modified);
00184         return ODS_STATUS_UNCHANGED;
00185     }
00186 
00187     new_sc = signconf_create();
00188     if (!new_sc) {
00189         ods_log_error("[%s] error creating new signconf", sc_str);
00190         return ODS_STATUS_ERR;
00191     }
00192 
00193     status = signconf_read(new_sc, scfile);
00194     if (status == ODS_STATUS_OK) {
00195         new_sc->last_modified = st_mtime;
00196         if (signconf_check(new_sc) != ODS_STATUS_OK) {
00197             ods_log_error("[%s] signconf %s has errors", sc_str, scfile);
00198             signconf_cleanup(new_sc);
00199             return ODS_STATUS_CFG_ERR;
00200         }
00201         *signconf = new_sc;
00202     } else {
00203         ods_log_error("[%s] unable to read file %s: %s", sc_str, scfile,
00204             ods_status2str(status));
00205         signconf_cleanup(new_sc);
00206     }
00207     return status;
00208 }
00209 
00210 
00215 signconf_type*
00216 signconf_recover_from_backup(const char* filename)
00217 {
00218     signconf_type* signconf = NULL;
00219     const char* zonename = NULL;
00220     FILE* scfd = NULL;
00221 
00222     scfd = ods_fopen(filename, NULL, "r");
00223     if (scfd) {
00224         signconf = signconf_create();
00225 
00226         if (!backup_read_check_str(scfd, ODS_SE_FILE_MAGIC) ||
00227             !backup_read_check_str(scfd, ";name:") ||
00228             !backup_read_str(scfd, &zonename) ||
00229             !backup_read_check_str(scfd, ";filename:") ||
00230             !backup_read_str(scfd, &signconf->filename) ||
00231             !backup_read_check_str(scfd, ";last_modified:") ||
00232             !backup_read_time_t(scfd, &signconf->last_modified) ||
00233             !backup_read_check_str(scfd, ";sig_resign_interval:") ||
00234             !backup_read_duration(scfd, &signconf->sig_resign_interval) ||
00235             !backup_read_check_str(scfd, ";sig_refresh_interval:") ||
00236             !backup_read_duration(scfd, &signconf->sig_refresh_interval) ||
00237             !backup_read_check_str(scfd, ";sig_validity_default:") ||
00238             !backup_read_duration(scfd, &signconf->sig_validity_default) ||
00239             !backup_read_check_str(scfd, ";sig_validity_denial:") ||
00240             !backup_read_duration(scfd, &signconf->sig_validity_denial) ||
00241             !backup_read_check_str(scfd, ";sig_jitter:") ||
00242             !backup_read_duration(scfd, &signconf->sig_jitter) ||
00243             !backup_read_check_str(scfd, ";sig_inception_offset:") ||
00244             !backup_read_duration(scfd, &signconf->sig_inception_offset) ||
00245             !backup_read_check_str(scfd, ";nsec_type:") ||
00246             !backup_read_rr_type(scfd, &signconf->nsec_type) ||
00247             !backup_read_check_str(scfd, ";dnskey_ttl:") ||
00248             !backup_read_duration(scfd, &signconf->dnskey_ttl) ||
00249             !backup_read_check_str(scfd, ";soa_ttl:") ||
00250             !backup_read_duration(scfd, &signconf->soa_ttl) ||
00251             !backup_read_check_str(scfd, ";soa_min:") ||
00252             !backup_read_duration(scfd, &signconf->soa_min) ||
00253             !backup_read_check_str(scfd, ";soa_serial:") ||
00254             !backup_read_str(scfd, &signconf->soa_serial) ||
00255             !backup_read_check_str(scfd, ";audit:") ||
00256             !backup_read_int(scfd, &signconf->audit) ||
00257             !backup_read_check_str(scfd, ODS_SE_FILE_MAGIC))
00258         {
00259             ods_log_error("[%s] unable to recover signconf backup file %s: corrupt "
00260                 "backup file ", sc_str, filename?filename:"(null)");
00261             signconf_cleanup(signconf);
00262             signconf = NULL;
00263         }
00264 
00265         if (zonename) {
00266             free((void*) zonename);
00267         }
00268         ods_fclose(scfd);
00269         return signconf;
00270     }
00271 
00272     ods_log_debug("[%s] unable to recover signconf backup file %s", sc_str,
00273         filename?filename:"(null)");
00274     return NULL;
00275 }
00276 
00277 
00282 static void
00283 signconf_backup_duration(FILE* fd, const char* opt, duration_type* duration)
00284 {
00285     char* str = duration2string(duration);
00286     fprintf(fd, "%s %s ", opt, str);
00287     free((void*) str);
00288     return;
00289 }
00290 
00291 
00292 
00297 void
00298 signconf_backup(FILE* fd, signconf_type* sc)
00299 {
00300     if (!fd || !sc) {
00301         return;
00302     }
00303     ods_log_assert(fd);
00304     ods_log_assert(sc);
00305 
00306     fprintf(fd, ";;Signconf: lastmod %u ", (unsigned) sc->last_modified);
00307     signconf_backup_duration(fd, "resign", sc->sig_resign_interval);
00308     signconf_backup_duration(fd, "refresh", sc->sig_refresh_interval);
00309     signconf_backup_duration(fd, "valid", sc->sig_validity_default);
00310     signconf_backup_duration(fd, "denial", sc->sig_validity_denial);
00311     signconf_backup_duration(fd, "jitter", sc->sig_jitter);
00312     signconf_backup_duration(fd, "offset", sc->sig_inception_offset);
00313     fprintf(fd, "nsec %u ", (unsigned) sc->nsec_type);
00314     signconf_backup_duration(fd, "dnskeyttl", sc->dnskey_ttl);
00315     signconf_backup_duration(fd, "soattl", sc->soa_ttl);
00316     signconf_backup_duration(fd, "soamin", sc->soa_min);
00317     fprintf(fd, "serial %s ", sc->soa_serial?sc->soa_serial:"(null)");
00318     fprintf(fd, "audit %i\n", sc->audit);
00319     return;
00320 }
00321 
00322 
00327 static int
00328 signconf_soa_serial_check(const char* serial) {
00329     if (!serial) {
00330         return 1;
00331     }
00332 
00333     if (strlen(serial) == 4 && strncmp(serial, "keep", 4) == 0) {
00334         return 0;
00335     }
00336     if (strlen(serial) == 7 && strncmp(serial, "counter", 7) == 0) {
00337         return 0;
00338     }
00339     if (strlen(serial) == 8 && strncmp(serial, "unixtime", 8) == 0) {
00340         return 0;
00341     }
00342     if (strlen(serial) == 11 && strncmp(serial, "datecounter", 11) == 0) {
00343         return 0;
00344     }
00345     return 1;
00346 }
00347 
00352 ods_status
00353 signconf_check(signconf_type* sc)
00354 {
00355     ods_status status = ODS_STATUS_OK;
00356 
00357     if (!sc->sig_resign_interval) {
00358         ods_log_error("[%s] check failed: no signature resign interval found",
00359             sc_str);
00360         status = ODS_STATUS_CFG_ERR;
00361     }
00362     if (!sc->sig_refresh_interval) {
00363         ods_log_error("[%s] check failed: no signature resign interval found",
00364             sc_str);
00365         status = ODS_STATUS_CFG_ERR;
00366     }
00367     if (!sc->sig_validity_default) {
00368         ods_log_error("[%s] check failed: no signature default validity found",
00369             sc_str);
00370         status = ODS_STATUS_CFG_ERR;
00371     }
00372     if (!sc->sig_validity_denial) {
00373         ods_log_error("[%s] check failed: no signature denial validity found",
00374             sc_str);
00375         status = ODS_STATUS_CFG_ERR;
00376     }
00377     if (!sc->sig_jitter) {
00378         ods_log_error("[%s] check failed: no signature jitter found", sc_str);
00379         status = ODS_STATUS_CFG_ERR;
00380     }
00381     if (!sc->sig_inception_offset) {
00382         ods_log_error("[%s] check failed: no signature inception offset found",
00383             sc_str);
00384         status = ODS_STATUS_CFG_ERR;
00385     }
00386     if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
00387         if (sc->nsec3_algo == 0) {
00388             ods_log_error("[%s] check failed: no nsec3 algorithm found",
00389                 sc_str);
00390             status = ODS_STATUS_CFG_ERR;
00391         }
00392         /* iterations */
00393         /* salt */
00394         /* optout */
00395     } else if (sc->nsec_type != LDNS_RR_TYPE_NSEC) {
00396         ods_log_error("[%s] check failed: wrong nsec type %i", sc_str,
00397             sc->nsec_type);
00398         status = ODS_STATUS_CFG_ERR;
00399     }
00400     if (!sc->keys || sc->keys->count == 0) {
00401         ods_log_error("[%s] check failed: no keys found", sc_str);
00402         status = ODS_STATUS_CFG_ERR;
00403     }
00404     if (!sc->dnskey_ttl) {
00405         ods_log_error("[%s] check failed: no dnskey ttl found", sc_str);
00406         status = ODS_STATUS_CFG_ERR;
00407     }
00408     if (!sc->soa_ttl) {
00409         ods_log_error("[%s] check failed: no soa ttl found", sc_str);
00410         status = ODS_STATUS_CFG_ERR;
00411     }
00412     if (!sc->soa_min) {
00413         ods_log_error("[%s] check failed: no soa minimum found", sc_str);
00414         status = ODS_STATUS_CFG_ERR;
00415     }
00416     if (!sc->soa_serial) {
00417         ods_log_error("[%s] check failed: no soa serial type found", sc_str);
00418         status = ODS_STATUS_CFG_ERR;
00419     } else if (signconf_soa_serial_check(sc->soa_serial) != 0) {
00420         ods_log_error("[%s] check failed: wrong soa serial type %s", sc_str,
00421             sc->soa_serial);
00422         status = ODS_STATUS_CFG_ERR;
00423     }
00424 
00425     return status;
00426 }
00427 
00428 
00433 task_id
00434 signconf_compare_denial(signconf_type* a, signconf_type* b)
00435 {
00436     task_id new_task = TASK_NONE;
00437     if (!a || !b) {
00438         return TASK_NONE;
00439     }
00440     ods_log_assert(a);
00441     ods_log_assert(b);
00442 
00443    if (a->nsec_type != b->nsec_type) {
00444        new_task = TASK_NSECIFY;
00445    } else if (a->nsec_type == LDNS_RR_TYPE_NSEC3) {
00446        if ((ods_strcmp(a->nsec3_salt, b->nsec3_salt) != 0) ||
00447            (a->nsec3_algo != b->nsec3_algo) ||
00448            (a->nsec3_iterations != b->nsec3_iterations) ||
00449            (a->nsec3_optout != b->nsec3_optout)) {
00450 
00451            new_task = TASK_NSECIFY;
00452        }
00453    } else if (duration_compare(a->soa_min, b->soa_min)) {
00454        new_task = TASK_NSECIFY;
00455    }
00456    return new_task;
00457 }
00458 
00459 
00464 task_id
00465 signconf_compare_keys(signconf_type* a, signconf_type* b, ldns_rr_list* del)
00466 {
00467    task_id new_task = TASK_NONE;
00468     ods_status status = ODS_STATUS_OK;
00469     key_type* walk = NULL;
00470     key_type* ka = NULL;
00471     key_type* kb = NULL;
00472     int remove = 0;
00473     int copy = 0;
00474 
00475     if (!a || !b) {
00476        return TASK_NONE;
00477     }
00478     ods_log_assert(a);
00479     ods_log_assert(b);
00480 
00481     /* keys deleted? */
00482     if (a->keys) {
00483         walk = a->keys->first_key;
00484     }
00485     while (walk && walk->locator) {
00486         remove = 0;
00487         copy = 0;
00488 
00489         kb = keylist_lookup(b->keys, walk->locator);
00490         if (!kb) {
00491             remove = 1; /* [DEL] key removed from signconf */
00492         } else {
00493             if (duration_compare(a->dnskey_ttl, b->dnskey_ttl) != 0) {
00494                 remove = 1; /* [DEL] consider to be different key */
00495             } else if (walk->flags != kb->flags) {
00496                 remove = 1; /* [DEL] consider to be different key */
00497             } else if (walk->algorithm != kb->algorithm) {
00498                 remove = 1; /* [DEL] consider to be different key */
00499             } else if (walk->publish != kb->publish) {
00500                 if (walk->publish) {
00501                     remove = 1; /* [DEL] withdraw dnskey from zone */
00502                 } else {
00503                     new_task = TASK_READ; /* [ADD] introduce key to zone */
00504                 }
00505             } else if (walk->ksk != kb->ksk) {
00506                 copy = 1; /* [UNCHANGED] same key, different role */
00507             } else if (walk->zsk != kb->zsk) {
00508                 copy = 1; /* [UNCHANGED] same key, different role */
00509             } else {
00510                 /* [UNCHANGED] identical key credentials */
00511                 copy = 1;
00512             }
00513         }
00514 
00515         if (remove) {
00516             new_task = TASK_READ;
00517             if (del && walk->dnskey) {
00518                 if (!ldns_rr_list_push_rr(del, walk->dnskey)) {
00519                     ods_log_error("[%s] del key failed", sc_str);
00520                     new_task = TASK_SIGNCONF;
00521                     break;
00522                 }
00523             }
00524         } else if (copy) {
00525             if (walk->dnskey && !kb->dnskey) {
00526                 kb->dnskey = walk->dnskey;
00527                 kb->hsmkey = walk->hsmkey;
00528                 status = lhsm_get_key(NULL, ldns_rr_owner(walk->dnskey), kb);
00529                 walk->hsmkey = NULL;
00530                 walk->dnskey = NULL;
00531             }
00532             if (status != ODS_STATUS_OK) {
00533                 ods_log_error("[%s] copy key failed", sc_str);
00534                 new_task = TASK_SIGNCONF;
00535                 break;
00536             }
00537         }
00538         walk = walk->next;
00539     }
00540 
00541     if (new_task == TASK_NONE) {
00542         /* no error and no keys were deleted, perhaps keys were added */
00543         walk = NULL;
00544         if (b->keys) {
00545             walk = b->keys->first_key;
00546         }
00547         while (walk) {
00548             ka = keylist_lookup(a->keys, walk->locator);
00549             if (!ka) {
00550                 new_task = TASK_READ; /* [ADD] key added to signconf */
00551                 break;
00552             }
00557             walk = walk->next;
00558         }
00559     }
00560    return new_task;
00561 }
00562 
00563 
00568 task_id
00569 signconf_compare(signconf_type* a, signconf_type* b)
00570 {
00571     task_id new_task = TASK_NONE;
00572     task_id tmp_task = TASK_NONE;
00573 
00574     new_task = signconf_compare_denial(a, b);
00575     tmp_task = signconf_compare_keys(a, b, NULL);
00576     if (tmp_task != TASK_NONE) {
00577         new_task = tmp_task;
00578     }
00579     /* not like python: reschedule if resign/refresh differs */
00580     /* this needs review, tasks correct on signconf changes? */
00581     return new_task;
00582 }
00583 
00584 
00589 void
00590 signconf_cleanup(signconf_type* sc)
00591 {
00592     allocator_type* allocator;
00593     if (!sc) {
00594         return;
00595     }
00596     duration_cleanup(sc->sig_resign_interval);
00597     duration_cleanup(sc->sig_refresh_interval);
00598     duration_cleanup(sc->sig_validity_default);
00599     duration_cleanup(sc->sig_validity_denial);
00600     duration_cleanup(sc->sig_jitter);
00601     duration_cleanup(sc->sig_inception_offset);
00602     duration_cleanup(sc->dnskey_ttl);
00603     duration_cleanup(sc->soa_ttl);
00604     duration_cleanup(sc->soa_min);
00605     keylist_cleanup(sc->keys);
00606 
00607     allocator = sc->allocator;
00608     allocator_deallocate(allocator, (void*) sc->filename);
00609     allocator_deallocate(allocator, (void*) sc->nsec3_salt);
00610     allocator_deallocate(allocator, (void*) sc->soa_serial);
00611     allocator_deallocate(allocator, (void*) sc);
00612     allocator_cleanup(allocator);
00613     return;
00614 }
00615 
00616 
00621 void
00622 signconf_print(FILE* out, signconf_type* sc, const char* name)
00623 {
00624     char* s = NULL;
00625 
00626     fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00627 
00628     if (sc) {
00629         fprintf(out, "<SignerConfiguration>\n");
00630         fprintf(out, "\t<Zone name=\"%s\">\n", name?name:"(null)");
00631 
00632         /* Signatures */
00633         fprintf(out, "\t\t<Signatures>\n");
00634         s = duration2string(sc->sig_resign_interval);
00635         fprintf(out, "\t\t\t<Resign>%s</Resign>\n", s?s:"(null)");
00636         free((void*)s);
00637 
00638         s = duration2string(sc->sig_refresh_interval);
00639         fprintf(out, "\t\t\t<Refresh>%s</Refresh>\n", s?s:"(null)");
00640         free((void*)s);
00641 
00642         fprintf(out, "\t\t\t<Validity>\n");
00643 
00644         s = duration2string(sc->sig_validity_default);
00645         fprintf(out, "\t\t\t\t<Default>%s</Default>\n", s?s:"(null)");
00646         free((void*)s);
00647 
00648         s = duration2string(sc->sig_validity_denial);
00649         fprintf(out, "\t\t\t\t<Denial>%s</Denial>\n", s?s:"(null)");
00650         free((void*)s);
00651 
00652         fprintf(out, "\t\t\t</Validity>\n");
00653 
00654         s = duration2string(sc->sig_jitter);
00655         fprintf(out, "\t\t\t<Jitter>%s</Jitter>\n", s?s:"(null)");
00656         free((void*)s);
00657 
00658         s = duration2string(sc->sig_inception_offset);
00659         fprintf(out, "\t\t\t<InceptionOffset>%s</InceptionOffset>\n",
00660             s?s:"(null)");
00661         free((void*)s);
00662 
00663         fprintf(out, "\t\t</Signatures>\n");
00664         fprintf(out, "\n");
00665 
00666         /* Denial */
00667         fprintf(out, "\t\t<Denial>\n");
00668         if (sc->nsec_type == LDNS_RR_TYPE_NSEC) {
00669             fprintf(out, "\t\t\t<NSEC />\n");
00670         } else if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
00671             fprintf(out, "\t\t\t<NSEC3>\n");
00672             if (sc->nsec3_optout) {
00673                 fprintf(out, "\t\t\t\t<OptOut />\n");
00674             }
00675             fprintf(out, "\t\t\t\t<Hash>\n");
00676             fprintf(out, "\t\t\t\t\t<Algorithm>%i</Algorithm>\n",
00677                 sc->nsec3_algo);
00678             fprintf(out, "\t\t\t\t\t<Iterations>%i</Iterations>\n",
00679                 sc->nsec3_iterations);
00680             fprintf(out, "\t\t\t\t\t<Salt>%s</Salt>\n",
00681                 sc->nsec3_salt?sc->nsec3_salt:"(null)");
00682             fprintf(out, "\t\t\t\t</Hash>\n");
00683             fprintf(out, "\t\t\t</NSEC3>\n");
00684         }
00685         fprintf(out, "\t\t</Denial>\n");
00686         fprintf(out, "\n");
00687 
00688         /* Keys */
00689         fprintf(out, "\t\t<Keys>\n");
00690         s = duration2string(sc->dnskey_ttl);
00691         fprintf(out, "\t\t\t<TTL>%s</TTL>\n", s?s:"(null)");
00692         free((void*)s);
00693         fprintf(out, "\n");
00694         keylist_print(out, sc->keys);
00695         fprintf(out, "\t\t</Keys>\n");
00696         fprintf(out, "\n");
00697 
00698         /* SOA */
00699         fprintf(out, "\t\t<SOA>\n");
00700         s = duration2string(sc->soa_ttl);
00701         fprintf(out, "\t\t\t<TTL>%s</TTL>\n", s?s:"(null)");
00702         free((void*)s);
00703 
00704         s = duration2string(sc->soa_min);
00705         fprintf(out, "\t\t\t<Minimum>%s</Minimum>\n", s?s:"(null)");
00706         free((void*)s);
00707 
00708         fprintf(out, "\t\t\t<Serial>%s</Serial>\n",
00709             sc->soa_serial?sc->soa_serial:"(null)");
00710         fprintf(out, "\t\t</SOA>\n");
00711         fprintf(out, "\n");
00712 
00713         /* Audit */
00714         if (sc->audit) {
00715             fprintf(out, "\t\t<Audit />\n");
00716             fprintf(out, "\n");
00717         }
00718 
00719         fprintf(out, "\t</Zone>\n");
00720         fprintf(out, "</SignerConfiguration>\n");
00721     }
00722     return;
00723 }
00724 
00725 
00730 void
00731 signconf_log(signconf_type* sc, const char* name)
00732 {
00733     char* resign = NULL;
00734     char* refresh = NULL;
00735     char* validity = NULL;
00736     char* denial = NULL;
00737     char* jitter = NULL;
00738     char* offset = NULL;
00739     char* dnskeyttl = NULL;
00740     char* soattl = NULL;
00741     char* soamin = NULL;
00742 
00743     if (sc) {
00744         resign = duration2string(sc->sig_resign_interval);
00745         refresh = duration2string(sc->sig_refresh_interval);
00746         validity = duration2string(sc->sig_validity_default);
00747         denial = duration2string(sc->sig_validity_denial);
00748         jitter = duration2string(sc->sig_jitter);
00749         offset = duration2string(sc->sig_inception_offset);
00750         dnskeyttl = duration2string(sc->dnskey_ttl);
00751         soattl = duration2string(sc->soa_ttl);
00752         soamin = duration2string(sc->soa_min);
00753 
00754         ods_log_info("[%s] zone %s signconf: RESIGN[%s] REFRESH[%s] "
00755             "VALIDITY[%s] DENIAL[%s] JITTER[%s] OFFSET[%s] NSEC[%i] "
00756             "DNSKEYTTL[%s] SOATTL[%s] MINIMUM[%s] SERIAL[%s] AUDIT[%i]",
00757             sc_str, name?name:"(null)", resign, refresh, validity, denial,
00758             jitter, offset, (int) sc->nsec_type, dnskeyttl, soattl,
00759             soamin, sc->soa_serial?sc->soa_serial:"(null)",
00760             (int) sc->audit);
00761 
00762         if (sc->nsec_type == LDNS_RR_TYPE_NSEC3) {
00763             ods_log_info("[%s] zone %s nsec3: OPTOUT[%i] ALGORITHM[%u] "
00764                 "ITERATIONS[%u] SALT[%s]", sc_str, name, sc->nsec3_optout,
00765                 sc->nsec3_algo, sc->nsec3_iterations,
00766                 sc->nsec3_salt?sc->nsec3_salt:"(null)");
00767         }
00768 
00769         /* Keys */
00770         keylist_log(sc->keys, name);
00771 
00772         free((void*)resign);
00773         free((void*)refresh);
00774         free((void*)validity);
00775         free((void*)denial);
00776         free((void*)jitter);
00777         free((void*)offset);
00778         free((void*)dnskeyttl);
00779         free((void*)soattl);
00780         free((void*)soamin);
00781     }
00782     return;
00783 }