OpenDNSSEC-signer 1.3.0rc3
|
00001 /* 00002 * $Id: rrset.c 5227 2011-06-12 08:51:24Z jakob $ 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 "config.h" 00035 #include "daemon/worker.h" 00036 #include "scheduler/fifoq.h" 00037 #include "shared/allocator.h" 00038 #include "shared/duration.h" 00039 #include "shared/file.h" 00040 #include "shared/hsm.h" 00041 #include "shared/log.h" 00042 #include "shared/status.h" 00043 #include "shared/util.h" 00044 #include "signer/rrset.h" 00045 00046 #include <ldns/ldns.h> 00047 #include <stdlib.h> 00048 00049 static const char* rrset_str = "rrset"; 00050 00051 00056 void 00057 log_rr(ldns_rr* rr, const char* pre, int level) 00058 { 00059 char* str = NULL; 00060 size_t i = 0; 00061 00062 if (ods_log_get_level() < level + 2) return; 00063 00064 str = ldns_rr2str(rr); 00065 if (str) { 00066 str[(strlen(str))-1] = '\0'; 00067 /* replace tabs with white space */ 00068 for (i=0; i < strlen(str); i++) { 00069 if (str[i] == '\t') { 00070 str[i] = ' '; 00071 } 00072 } 00073 00074 if (level == 1) { /* LOG_ERR */ 00075 ods_log_error("%s %s", pre?pre:"", str); 00076 } else if (level == 2) { /* LOG_WARNING */ 00077 ods_log_warning("%s %s", pre?pre:"", str); 00078 } else if (level == 3) { /* LOG_NOTICE */ 00079 ods_log_info("%s %s", pre?pre:"", str); 00080 } else if (level == 4) { /* LOG_INFO */ 00081 ods_log_verbose("%s %s", pre?pre:"", str); 00082 } else if (level == 5) { /* LOG_DEBUG */ 00083 ods_log_debug("%s %s", pre?pre:"", str); 00084 } else if (level == 6) { /* more debugging */ 00085 ods_log_deeebug("%s %s", pre?pre:"", str); 00086 } else { /* hardcore debugging */ 00087 ods_log_deeebug("%s %s", pre?pre:"", str); 00088 } 00089 free((void*)str); 00090 } 00091 return; 00092 } 00093 00094 00099 rrset_type* 00100 rrset_create(ldns_rr_type rrtype) 00101 { 00102 allocator_type* allocator = NULL; 00103 rrset_type* rrset = NULL; 00104 00105 if (!rrtype) { 00106 ods_log_error("[%s] unable to create RRset: no RRtype", rrset_str); 00107 return NULL; 00108 } 00109 ods_log_assert(rrtype); 00110 00111 allocator = allocator_create(malloc, free); 00112 if (!allocator) { 00113 ods_log_error("[%s] unable to create RRset %u: create allocator " 00114 "failed", rrset_str, (unsigned) rrtype); 00115 return NULL; 00116 } 00117 ods_log_assert(allocator); 00118 00119 rrset = (rrset_type*) allocator_alloc(allocator, sizeof(rrset_type)); 00120 if (!rrset) { 00121 ods_log_error("[%s] unable to create RRset %u: allocator failed", 00122 rrset_str, (unsigned) rrtype); 00123 allocator_cleanup(allocator); 00124 return NULL; 00125 } 00126 ods_log_assert(rrset); 00127 00128 rrset->allocator = allocator; 00129 rrset->rr_type = rrtype; 00130 rrset->rr_count = 0; 00131 rrset->add_count = 0; 00132 rrset->del_count = 0; 00133 rrset->rrsig_count = 0; 00134 rrset->needs_signing = 0; 00135 rrset->rrs = ldns_dnssec_rrs_new(); 00136 rrset->add = NULL; 00137 rrset->del = NULL; 00138 rrset->rrsigs = NULL; 00139 return rrset; 00140 } 00141 00142 00147 ods_status 00148 rrset_recover(rrset_type* rrset, ldns_rr* rrsig, const char* locator, 00149 uint32_t flags) 00150 { 00151 ods_status status = ODS_STATUS_OK; 00152 00153 ods_log_assert(rrset); 00154 ods_log_assert(rrsig); 00155 ods_log_assert(locator); 00156 ods_log_assert(flags); 00157 00158 if (!rrset->rrsigs) { 00159 rrset->rrsigs = rrsigs_create(); 00160 } 00161 00162 status = rrsigs_add_sig(rrset->rrsigs, rrsig, locator, flags); 00163 if (status != ODS_STATUS_OK) { 00164 ods_log_error("[%s] unable to recover RRSIG", rrset_str); 00165 log_rr(rrsig, "+RRSIG", 1); 00166 } else { 00167 rrset->rrsig_count += 1; 00173 rrset->needs_signing = 0; 00174 } 00175 return status; 00176 } 00177 00178 00183 static int 00184 rrs_examine_ns_rdata(ldns_dnssec_rrs* rrs, ldns_rdf* nsdname) 00185 { 00186 ldns_dnssec_rrs* walk = NULL; 00187 if (!rrs || !nsdname) { 00188 return 0; 00189 } 00190 walk = rrs; 00191 while (walk) { 00192 if (walk->rr && 00193 ldns_dname_compare(ldns_rr_rdf(walk->rr, 0), nsdname) == 0) { 00194 return 1; 00195 } 00196 walk = walk->next; 00197 } 00198 return 0; 00199 } 00200 00201 00206 int 00207 rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname) 00208 { 00209 if (!rrset || !nsdname || rrset->rr_type != LDNS_RR_TYPE_NS) { 00210 return 0; 00211 } 00212 if (rrs_examine_ns_rdata(rrset->add, nsdname)) { 00213 return 1; 00214 } 00215 if (rrs_examine_ns_rdata(rrset->del, nsdname)) { 00216 return 0; 00217 } 00218 return rrs_examine_ns_rdata(rrset->rrs, nsdname); 00219 } 00220 00221 00226 size_t 00227 rrset_count_RR(rrset_type* rrset) 00228 { 00229 ods_log_assert(rrset); 00230 return ((rrset->rr_count + rrset->add_count) - rrset->del_count); 00231 } 00232 00233 00238 size_t 00239 rrset_count_rr(rrset_type* rrset, int which) 00240 { 00241 if (!rrset) { 00242 return 0; 00243 } 00244 switch (which) { 00245 case COUNT_ADD: 00246 return rrset->add_count; 00247 case COUNT_DEL: 00248 return rrset->del_count; 00249 case COUNT_RR: 00250 default: 00251 return rrset->rr_count; 00252 } 00253 /* not reached */ 00254 return rrset->rr_count; 00255 } 00256 00257 00262 ldns_rr* 00263 rrset_add_rr(rrset_type* rrset, ldns_rr* rr) 00264 { 00265 ldns_status status = LDNS_STATUS_OK; 00266 00267 if (!rr) { 00268 ods_log_error("[%s] unable to add RR: no RR", rrset_str); 00269 return NULL; 00270 } 00271 ods_log_assert(rr); 00272 00273 if (!rrset) { 00274 ods_log_error("[%s] unable to add RR: no storage", rrset_str); 00275 return NULL; 00276 } 00277 ods_log_assert(rrset); 00278 00279 if (rrset->rr_type != ldns_rr_get_type(rr)) { 00280 ods_log_error("[%s] unable to add RR: RRtype mismatch", rrset_str); 00281 return NULL; 00282 } 00283 00284 if (!rrset->add) { 00285 rrset->add = ldns_dnssec_rrs_new(); 00286 } 00287 00288 if (!rrset->add->rr) { 00289 rrset->add->rr = rr; 00290 rrset->add_count = 1; 00291 log_rr(rr, "+rr", 7); 00292 } else { 00293 status = util_dnssec_rrs_add_rr(rrset->add, rr); 00294 if (status != LDNS_STATUS_OK) { 00295 if (status == LDNS_STATUS_NO_DATA) { 00296 ods_log_warning("[%s] unable to add RR to RRset (%i): " 00297 "duplicate", rrset_str, rrset->rr_type); 00298 log_rr(rr, "+rr", 2); 00299 /* filter out duplicates */ 00300 return rr; 00301 } else { 00302 ods_log_error("[%s] unable to add RR to RRset (%i): %s", 00303 rrset_str, rrset->rr_type, 00304 ldns_get_errorstr_by_id(status)); 00305 log_rr(rr, "+rr", 1); 00306 ldns_dnssec_rrs_deep_free(rrset->add); 00307 rrset->add = NULL; 00308 rrset->add_count = 0; 00309 return NULL; 00310 } 00311 } 00312 rrset->add_count += 1; 00313 log_rr(rr, "+rr", 7); 00314 } 00315 return rr; 00316 } 00317 00318 00323 ldns_rr* 00324 rrset_del_rr(rrset_type* rrset, ldns_rr* rr, int dupallowed) 00325 { 00326 ldns_status status = LDNS_STATUS_OK; 00327 00328 if (!rr) { 00329 ods_log_error("[%s] unable to delete RR: no RR", rrset_str); 00330 return NULL; 00331 } 00332 ods_log_assert(rr); 00333 00334 if (!rrset) { 00335 ods_log_error("[%s] unable to delete RR: no storage", rrset_str); 00336 return NULL; 00337 } 00338 ods_log_assert(rrset); 00339 00340 if (rrset->rr_type != ldns_rr_get_type(rr)) { 00341 ods_log_error("[%s] unable to delete RR: RRtype mismatch", rrset_str); 00342 return NULL; 00343 } 00344 00345 if (!rrset->del) { 00346 rrset->del = ldns_dnssec_rrs_new(); 00347 } 00348 00349 if (!rrset->del->rr) { 00350 rrset->del->rr = rr; 00351 rrset->del_count = 1; 00352 log_rr(rr, "-rr", 7); 00353 } else { 00354 status = util_dnssec_rrs_add_rr(rrset->del, rr); 00355 if (status != LDNS_STATUS_OK) { 00356 if (status == LDNS_STATUS_NO_DATA) { 00357 if (dupallowed) { 00358 return rr; 00359 } 00360 ods_log_warning("[%s] unable to delete RR from RRset (%i): " 00361 "duplicate", rrset_str, rrset->rr_type); 00362 log_rr(rr, "-rr", 2); 00363 /* filter out duplicates */ 00364 return rr; 00365 } else { 00366 ods_log_error("[%s] unable to delete RR from RRset (%i): %s", 00367 rrset_str, rrset->rr_type, 00368 ldns_get_errorstr_by_id(status)); 00369 log_rr(rr, "-rr", 1); 00370 ldns_dnssec_rrs_deep_free(rrset->del); 00371 rrset->del = NULL; 00372 rrset->del_count = 0; 00373 return NULL; 00374 } 00375 } 00376 rrset->del_count += 1; 00377 log_rr(rr, "-rr", 7); 00378 } 00379 return rr; 00380 } 00381 00382 00387 ods_status 00388 rrset_wipe_out(rrset_type* rrset) 00389 { 00390 ldns_dnssec_rrs* rrs = NULL; 00391 ldns_rr* del_rr = NULL; 00392 int error = 0; 00393 00394 if (rrset) { 00395 rrs = rrset->rrs; 00396 } 00397 00398 while (rrs) { 00399 if (rrs->rr) { 00400 del_rr = ldns_rr_clone(rrs->rr); 00401 if (rrset_del_rr(rrset, del_rr, 00402 (ldns_rr_get_type(del_rr) == LDNS_RR_TYPE_DNSKEY)) == NULL) { 00403 ods_log_error("[%s] unable to wipe RR from RRset (%i)", 00404 rrset_str, rrset->rr_type); 00405 ldns_rr_free(del_rr); 00406 error = 1; 00407 } 00408 del_rr = NULL; 00409 } 00410 rrs = rrs->next; 00411 } 00412 00413 if (error) { 00414 return ODS_STATUS_ERR; 00415 } 00416 return ODS_STATUS_OK; 00417 } 00418 00419 00424 ods_status 00425 rrset_diff(rrset_type* rrset, keylist_type* kl) 00426 { 00427 ods_status status = ODS_STATUS_OK; 00428 ldns_status lstatus = LDNS_STATUS_OK; 00429 ldns_dnssec_rrs* current = NULL; 00430 ldns_dnssec_rrs* pending = NULL; 00431 ldns_dnssec_rrs* prev = NULL; 00432 ldns_rr* rr = NULL; 00433 int cmp = 0; 00434 00435 if (!rrset) { 00436 return status; 00437 } 00438 00439 current = rrset->rrs; 00440 pending = rrset->add; 00441 00442 if (!current || !current->rr) { 00443 current = NULL; 00444 } 00445 if (!pending || !pending->rr) { 00446 pending = NULL; 00447 } 00448 00449 while (current && pending) { 00450 lstatus = util_dnssec_rrs_compare(current->rr, pending->rr, &cmp); 00451 if (lstatus != LDNS_STATUS_OK) { 00452 ods_log_error("[%s] diff failed: compare failed (%s)", 00453 rrset_str, ldns_get_errorstr_by_id(lstatus)); 00454 return ODS_STATUS_ERR; 00455 } 00456 00457 if (cmp > 0) { 00458 prev = pending; 00459 pending = pending->next; 00460 } else if (cmp < 0) { 00461 /* pend current RR to be removed */ 00462 if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY || 00463 !keylist_lookup_by_dnskey(kl, current->rr)) { 00464 00465 rr = ldns_rr_clone(current->rr); 00466 rr = rrset_del_rr(rrset, rr, 00467 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY)); 00468 if (!rr) { 00469 ods_log_error("[%s] diff failed: failed to delete RR", 00470 rrset_str); 00471 return ODS_STATUS_ERR; 00472 } 00473 } 00474 00475 current = current->next; 00476 } else { /* equal RRs */ 00477 /* remove pending RR */ 00478 if (!prev) { 00479 rrset->add = pending->next; 00480 } else { 00481 prev->next = pending->next; 00482 } 00483 pending->next = NULL; 00484 rrset->add_count -= 1; 00485 00486 ldns_dnssec_rrs_deep_free(pending); 00487 pending = NULL; 00488 00489 current = current->next; 00490 if (!prev) { 00491 pending = rrset->add; 00492 } else { 00493 pending = prev->next; 00494 } 00495 } 00496 } 00497 00498 if (pending) { 00499 ods_log_assert(!current); 00500 /* all newly added RRs */ 00501 } 00502 00503 if (current) { 00504 ods_log_assert(!pending); 00505 while (current) { 00506 /* pend current RR to be removed */ 00507 if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY || 00508 !keylist_lookup_by_dnskey(kl, current->rr)) { 00509 00510 rr = ldns_rr_clone(current->rr); 00511 rr = rrset_del_rr(rrset, rr, 00512 (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY)); 00513 if (!rr) { 00514 ods_log_error("[%s] diff failed: failed to delete RR", 00515 rrset_str); 00516 return ODS_STATUS_ERR; 00517 } 00518 } 00519 current = current->next; 00520 } 00521 } 00522 return ODS_STATUS_OK; 00523 } 00524 00525 00530 static ods_status 00531 rrset_commit_del(rrset_type* rrset, ldns_rr* rr) 00532 { 00533 ldns_status status = LDNS_STATUS_OK; 00534 ldns_dnssec_rrs* rrs = NULL; 00535 ldns_dnssec_rrs* prev_rrs = NULL; 00536 int cmp = 0; 00537 00538 if (!rr) { 00539 ods_log_error("[%s] unable to commit del RR: no RR", rrset_str); 00540 return ODS_STATUS_ASSERT_ERR; 00541 } 00542 ods_log_assert(rr); 00543 if (!rrset) { 00544 ods_log_error("[%s] unable to commit del RR: no storage", rrset_str); 00545 return ODS_STATUS_ASSERT_ERR; 00546 } 00547 ods_log_assert(rrset); 00548 00549 rrs = rrset->rrs; 00550 while (rrs) { 00551 status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp); 00552 if (status != LDNS_STATUS_OK) { 00553 ods_log_error("[%s] unable to commit del RR: compare failed", 00554 rrset_str); 00555 return ODS_STATUS_ERR; 00556 } 00557 00558 if (cmp == 0) { 00559 /* this is it */ 00560 if (prev_rrs) { 00561 prev_rrs->next = rrs->next; 00562 } else { 00563 rrset->rrs = rrs->next; 00564 } 00565 rrs->next = NULL; 00566 ldns_dnssec_rrs_deep_free(rrs); 00567 rrs = NULL; 00568 00569 rrset->rr_count -= 1; 00570 rrset->del_count -= 1; 00571 log_rr(rr, "-RR", 6); 00572 return ODS_STATUS_OK; 00573 } 00574 00575 /* keep looking */ 00576 prev_rrs = rrs; 00577 rrs = rrs->next; 00578 } 00579 00580 ods_log_warning("[%s] unable to commit del RR: no such RR", rrset_str); 00581 log_rr(rr, "-RR", 2); 00582 return ODS_STATUS_UNCHANGED; 00583 } 00584 00585 00590 static ods_status 00591 rrset_commit_add(rrset_type* rrset, ldns_rr* rr) 00592 { 00593 ldns_status status = LDNS_STATUS_OK; 00594 00595 if (!rr) { 00596 ods_log_error("[%s] unable to commit add RR: no RR", rrset_str); 00597 return ODS_STATUS_ASSERT_ERR; 00598 } 00599 ods_log_assert(rr); 00600 if (!rrset) { 00601 ods_log_error("[%s] unable to commit add RR: no storage", rrset_str); 00602 return ODS_STATUS_ASSERT_ERR; 00603 } 00604 ods_log_assert(rrset); 00605 00606 if (!rrset->rrs) { 00607 rrset->rrs = ldns_dnssec_rrs_new(); 00608 } 00609 00610 if (!rrset->rrs->rr) { 00611 rrset->rrs->rr = rr; 00612 rrset->rr_count += 1; 00613 rrset->add_count -= 1; 00614 log_rr(rr, "+RR", 6); 00615 return ODS_STATUS_OK; 00616 } else { 00617 status = util_dnssec_rrs_add_rr(rrset->rrs, rr); 00618 if (status != LDNS_STATUS_OK) { 00619 if (status == LDNS_STATUS_NO_DATA) { 00620 ods_log_warning("[%s] unable to commit add RR: duplicate", 00621 rrset_str); 00622 log_rr(rr, "+RR", 2); 00623 return ODS_STATUS_UNCHANGED; 00624 } else { 00625 ods_log_error("[%s] unable to commit add RR: %s", 00626 rrset_str, ldns_get_errorstr_by_id(status)); 00627 log_rr(rr, "+RR", 1); 00628 return ODS_STATUS_ERR; 00629 } 00630 } 00631 log_rr(rr, "+RR", 6); 00632 rrset->rr_count += 1; 00633 rrset->add_count -= 1; 00634 return ODS_STATUS_OK; 00635 } 00636 /* not reached */ 00637 return ODS_STATUS_ERR; 00638 } 00639 00640 00645 ods_status 00646 rrset_commit(rrset_type* rrset) 00647 { 00648 ldns_dnssec_rrs* rrs = NULL; 00649 ods_status status = ODS_STATUS_OK; 00650 00651 if (!rrset) { 00652 return ODS_STATUS_ASSERT_ERR; 00653 } 00654 ods_log_assert(rrset); 00655 00656 if (rrset->del_count || rrset->add_count) { 00657 rrset->needs_signing = 1; 00658 } 00659 00660 /* delete RRs */ 00661 rrs = rrset->del; 00662 while (rrs) { 00663 status = rrset_commit_del(rrset, rrs->rr); 00664 if (status != ODS_STATUS_OK) { 00665 ods_log_alert("[%s] commit RRset (%i) failed", rrset_str, 00666 rrset->rr_type); 00667 return status; 00668 } 00669 rrs = rrs->next; 00670 } 00671 ldns_dnssec_rrs_deep_free(rrset->del); 00672 rrset->del = NULL; 00673 rrset->del_count = 0; 00674 00675 /* add RRs */ 00676 rrs = rrset->add; 00677 while (rrs) { 00678 status = rrset_commit_add(rrset, rrs->rr); 00679 if (status != ODS_STATUS_OK) { 00680 ods_log_alert("[%s] commit RRset (%i) failed", rrset_str, 00681 rrset->rr_type); 00682 return status; 00683 } 00684 rrs = rrs->next; 00685 } 00686 ldns_dnssec_rrs_free(rrset->add); 00687 rrset->add = NULL; 00688 rrset->add_count = 0; 00689 00690 /* update serial */ 00691 00692 return ODS_STATUS_OK; 00693 } 00694 00695 00700 void 00701 rrset_rollback(rrset_type* rrset) 00702 { 00703 if (!rrset) { 00704 return; 00705 } 00706 00707 if (rrset->add) { 00708 ldns_dnssec_rrs_deep_free(rrset->add); 00709 rrset->add = NULL; 00710 rrset->add_count = 0; 00711 } 00712 if (rrset->del) { 00713 ldns_dnssec_rrs_deep_free(rrset->del); 00714 rrset->del = NULL; 00715 rrset->del_count = 0; 00716 } 00717 return; 00718 } 00719 00720 00725 static uint32_t 00726 rrset_recycle(rrset_type* rrset, signconf_type* sc, time_t signtime) 00727 { 00728 rrsigs_type* rrsigs = NULL; 00729 rrsigs_type* prev_rrsigs = NULL; 00730 rrsigs_type* next_rrsigs = NULL; 00731 uint32_t refresh = 0; 00732 uint32_t expiration = 0; 00733 uint32_t inception = 0; 00734 uint32_t reusedsigs = 0; 00735 int drop_sig = 0; 00736 key_type* key = NULL; 00737 00738 /* Calculate the Refresh Window = Signing time + Refresh */ 00739 if (sc && sc->sig_refresh_interval) { 00740 refresh = (uint32_t) (signtime + 00741 duration2time(sc->sig_refresh_interval)); 00742 } 00743 00744 /* 1. If the RRset has changed, drop all signatures */ 00745 /* 2. If Refresh is disabled, drop all signatures */ 00746 if (rrset->needs_signing || !refresh) { 00747 ods_log_debug("[%s] drop signatures for RRset[%i]", rrset_str, 00748 rrset->rr_type); 00749 if (rrset->rrsigs) { 00750 rrsigs_cleanup(rrset->rrsigs); 00751 rrset->rrsigs = NULL; 00752 } 00753 rrset->rrsig_count = 0; 00754 rrset->needs_signing = 0; 00755 return 0; 00756 } 00757 00758 /* 3. Check every signature if it matches the recycling logic. */ 00759 rrsigs = rrset->rrsigs; 00760 while (rrsigs) { 00761 if (!rrsigs->rr) { 00762 ods_log_warning("[%s] signature set has no RRSIG record: " 00763 "drop signatures for RRset[%i]", rrset_str, rrset->rr_type); 00764 rrsigs_cleanup(rrset->rrsigs); 00765 rrset->rrsigs = NULL; 00766 rrset->rrsig_count = 0; 00767 rrset->needs_signing = 0; 00768 return 0; 00769 } 00770 00771 expiration = ldns_rdf2native_int32( 00772 ldns_rr_rrsig_expiration(rrsigs->rr)); 00773 inception = ldns_rdf2native_int32( 00774 ldns_rr_rrsig_inception(rrsigs->rr)); 00775 00776 if (expiration < refresh) { 00777 /* 3a. Expiration - Refresh has passed */ 00778 drop_sig = 1; 00779 ods_log_deeebug("[%s] refresh signature for RRset[%i]: " 00780 "expiration minus refresh has passed: %u - %u < (signtime)", 00781 rrset_str, rrset->rr_type, expiration, refresh, 00782 (uint32_t) signtime); 00783 } else if (inception > (uint32_t) signtime) { 00784 /* 3b. Inception has not yet passed */ 00785 drop_sig = 1; 00786 ods_log_deeebug("[%s] refresh signature for RRset[%i]: " 00787 "inception has not passed: %u < %u (signtime)", rrset_str, 00788 rrset->rr_type, inception, (uint32_t) signtime); 00789 } else { 00790 /* 3c. Corresponding key is dead (key is locator+flags) */ 00791 key = keylist_lookup(sc->keys, rrsigs->key_locator); 00792 if (!key) { 00793 drop_sig = 1; 00794 ods_log_deeebug("[%s] refresh signature for RRset[%i]: " 00795 "key %s %u is dead", rrset_str, 00796 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags); 00797 } else if (key->flags != rrsigs->key_flags) { 00798 drop_sig = 1; 00799 ods_log_deeebug("[%s] refresh signature for RRset[%i]: " 00800 "key %s %u flags mismatch", rrset_str, 00801 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags); 00802 } 00803 } 00804 00805 next_rrsigs = rrsigs->next; 00806 if (drop_sig) { 00807 /* A rule mismatched, refresh signature */ 00808 if (prev_rrsigs) { 00809 prev_rrsigs->next = rrsigs->next; 00810 } else { 00811 rrset->rrsigs = rrsigs->next; 00812 } 00813 log_rr(rrsigs->rr, "-RRSIG", 6); 00814 rrset->rrsig_count -= 1; 00815 rrsigs->next = NULL; 00816 rrsigs_cleanup(rrsigs); 00817 } else { 00818 /* All rules ok, recycle signature */ 00819 ods_log_deeebug("[%s] recycle signature for RRset[%i] " 00820 "(refresh=%u, signtime=%u, inception=%u, expiration=%u)", 00821 rrset_str, rrset->rr_type, refresh, (uint32_t) signtime, 00822 inception, expiration); 00823 log_rr(rrsigs->rr, "*RRSIG", 7); 00824 reusedsigs += 1; 00825 prev_rrsigs = rrsigs; 00826 } 00827 drop_sig = 0; 00828 rrsigs = next_rrsigs; 00829 } 00830 return reusedsigs; 00831 } 00832 00833 00838 static int 00839 rrset_signed_with_algorithm(rrset_type* rrset, uint8_t algorithm) 00840 { 00841 rrsigs_type* rrsigs = NULL; 00842 00843 if (!rrset || !algorithm) { 00844 return 0; 00845 } 00846 00847 rrsigs = rrset->rrsigs; 00848 while (rrsigs) { 00849 if (rrsigs->rr && algorithm == 00850 ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsigs->rr))) { 00851 return 1; 00852 } 00853 rrsigs = rrsigs->next; 00854 } 00855 00856 return 0; 00857 } 00858 00859 00864 static ldns_rr_list* 00865 rrset2rrlist(rrset_type* rrset) 00866 { 00867 ldns_dnssec_rrs* rrs = NULL; 00868 ldns_rr_list* rr_list = NULL; 00869 int error = 0; 00870 00871 rr_list = ldns_rr_list_new(); 00872 rrs = rrset->rrs; 00873 while (rrs && rrs->rr) { 00874 error = (int) ldns_rr_list_push_rr(rr_list, rrs->rr); 00875 if (!error) { 00876 ldns_rr_list_free(rr_list); 00877 return NULL; 00878 } 00879 if (rrset->rr_type == LDNS_RR_TYPE_CNAME || 00880 rrset->rr_type == LDNS_RR_TYPE_DNAME) { 00881 /* singleton types */ 00882 return rr_list; 00883 } 00884 rrs = rrs->next; 00885 } 00886 return rr_list; 00887 } 00888 00889 00894 static void 00895 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime, 00896 time_t* inception, time_t* expiration) 00897 { 00898 time_t jitter = 0; 00899 time_t offset = 0; 00900 time_t validity = 0; 00901 time_t random_jitter = 0; 00902 00903 if (!sc || !rrtype || !signtime) { 00904 return; 00905 } 00906 00907 jitter = duration2time(sc->sig_jitter); 00908 if (jitter) { 00909 random_jitter = ods_rand(jitter*2); 00910 } 00911 offset = duration2time(sc->sig_inception_offset); 00912 if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) { 00913 validity = duration2time(sc->sig_validity_denial); 00914 } else { 00915 validity = duration2time(sc->sig_validity_default); 00916 } 00917 00921 if (((validity + offset + random_jitter) - jitter) < 00922 ((validity + offset) - jitter) ) { 00923 ods_log_error("[%s] signature validity %u too low, should be at " 00924 "least %u", rrset_str, 00925 ((validity + offset + random_jitter) - jitter), 00926 ((validity + offset) - jitter)); 00927 } else if (((validity + offset + random_jitter) - jitter) > 00928 ((validity + offset) + jitter) ) { 00929 ods_log_error("[%s] signature validity %u too high, should be at " 00930 "most %u", rrset_str, 00931 ((validity + offset + random_jitter) - jitter), 00932 ((validity + offset) + jitter)); 00933 } else { 00934 ods_log_debug("[%s] signature validity %u in range [%u - %u]", 00935 rrset_str, ((validity + offset + random_jitter) - jitter), 00936 ((validity + offset) - jitter), 00937 ((validity + offset) + jitter)); 00938 } 00939 *inception = signtime - offset; 00940 *expiration = (signtime + validity + random_jitter) - jitter; 00941 return; 00942 } 00943 00944 00949 ods_status 00950 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, ldns_rdf* owner, 00951 signconf_type* sc, time_t signtime, stats_type* stats) 00952 { 00953 ods_status status = ODS_STATUS_OK; 00954 uint32_t newsigs = 0; 00955 uint32_t reusedsigs = 0; 00956 ldns_rr* rrsig = NULL; 00957 ldns_rr_list* rr_list = NULL; 00958 rrsigs_type* new_rrsigs = NULL; 00959 rrsigs_type* walk_rrsigs = NULL; 00960 key_type* key = NULL; 00961 time_t inception = 0; 00962 time_t expiration = 0; 00963 00964 if (!rrset) { 00965 ods_log_error("[%s] unable to sign RRset: no RRset", rrset_str); 00966 return ODS_STATUS_ASSERT_ERR; 00967 } 00968 ods_log_assert(rrset); 00969 00970 if (!owner) { 00971 ods_log_error("[%s] unable to sign RRset: no owner", rrset_str); 00972 return ODS_STATUS_ASSERT_ERR; 00973 } 00974 ods_log_assert(owner); 00975 00976 if (!sc) { 00977 ods_log_error("[%s] unable to sign RRset: no signconf", rrset_str); 00978 return ODS_STATUS_ASSERT_ERR; 00979 } 00980 ods_log_assert(sc); 00981 00982 /* recycle signatures */ 00983 reusedsigs = rrset_recycle(rrset, sc, signtime); 00984 00985 /* transmogrify the RRset */ 00986 rr_list = rrset2rrlist(rrset); 00987 if (!rr_list) { 00988 ods_log_error("[%s] unable to sign RRset[%i]: to RRlist failed", 00989 rrset->rr_type); 00990 return ODS_STATUS_ERR; 00991 } 00992 if (ldns_rr_list_rr_count(rr_list) <= 0) { 00993 /* empty RRset, no signatures needed */ 00994 ldns_rr_list_free(rr_list); 00995 return ODS_STATUS_OK; 00996 } 00997 00998 /* prepare for signing */ 00999 new_rrsigs = rrsigs_create(); 01000 if (!rrset->rrsigs) { 01001 rrset->rrsigs = rrsigs_create(); 01002 } 01003 rrset_sigvalid_period(sc, rrset->rr_type, signtime, 01004 &inception, &expiration); 01005 01006 key = sc->keys->first_key; 01007 while (key) { 01008 /* ksk or zsk ? */ 01009 if (!key->zsk && rrset->rr_type != LDNS_RR_TYPE_DNSKEY) { 01010 ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no " 01011 "active ZSK", rrset_str, key->locator, rrset->rr_type); 01012 key = key->next; 01013 continue; 01014 } 01015 if (!key->ksk && rrset->rr_type == LDNS_RR_TYPE_DNSKEY) { 01016 ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no " 01017 "active KSK", rrset_str, key->locator, rrset->rr_type); 01018 key = key->next; 01019 continue; 01020 } 01021 01022 /* is there a signature with this algorithm already? */ 01023 if (rrset_signed_with_algorithm(rrset, key->algorithm)) { 01024 ods_log_deeebug("skipping key %s for signing: RRset[%i] " 01025 "already has signature with same algorithm", key->locator); 01026 key = key->next; 01027 continue; 01028 } 01029 01035 /* sign the RRset with current key */ 01036 ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str, 01037 rrset->rr_type, key->locator); 01038 rrsig = lhsm_sign(ctx, rr_list, key, owner, inception, expiration); 01039 if (!rrsig) { 01040 ods_log_error("[%s] unable to sign RRset[%i]: error creating " 01041 "RRSIG RR", rrset_str, rrset->rr_type); 01042 ldns_rr_list_free(rr_list); 01043 rrsigs_cleanup(new_rrsigs); 01044 return ODS_STATUS_ERR; 01045 } 01046 /* add the signature to the set of new signatures */ 01047 ods_log_deeebug("[%s] new signature created for RRset[%i]", rrset_str, 01048 rrset->rr_type); 01049 log_rr(rrsig, "+rrsig", 7); 01050 status = rrsigs_add_sig(new_rrsigs, rrsig, key->locator, key->flags); 01051 if (status != ODS_STATUS_OK) { 01052 ods_log_error("[%s] unable to sign RRset[%i]: error adding RRSIG", 01053 rrset_str, rrset->rr_type); 01054 log_rr(rrsig, "+RRSIG", 1); 01055 ldns_rr_list_free(rr_list); 01056 rrsigs_cleanup(new_rrsigs); 01057 return status; 01058 } 01059 /* next key */ 01060 key = key->next; 01061 } 01062 01063 /* signing completed, add the signatures to the right RRset */ 01064 walk_rrsigs = new_rrsigs; 01065 while (walk_rrsigs) { 01066 if (walk_rrsigs->rr) { 01067 ods_log_deeebug("[%s] adding signature to RRset[%i]", rrset_str, 01068 rrset->rr_type); 01069 status = rrsigs_add_sig(rrset->rrsigs, 01070 ldns_rr_clone(walk_rrsigs->rr), 01071 walk_rrsigs->key_locator, walk_rrsigs->key_flags); 01072 if (status != ODS_STATUS_OK) { 01073 ods_log_error("[%s] unable to sign RRset[%i]: error adding " 01074 "RRSIG to RRset[%i]", rrset_str, rrset->rr_type, 01075 rrset->rr_type); 01076 log_rr(walk_rrsigs->rr, "+RRSIG", 1); 01077 ldns_rr_list_free(rr_list); 01078 rrsigs_cleanup(new_rrsigs); 01079 return status; 01080 } 01081 rrset->rrsig_count += 1; 01082 newsigs++; 01083 log_rr(walk_rrsigs->rr, "+RRSIG", 6); 01084 } 01085 walk_rrsigs = walk_rrsigs->next; 01086 } 01087 01088 /* clean up */ 01089 rrsigs_cleanup(new_rrsigs); 01090 ldns_rr_list_free(rr_list); 01091 01092 lock_basic_lock(&stats->stats_lock); 01093 if (rrset->rr_type == LDNS_RR_TYPE_SOA) { 01094 stats->sig_soa_count += newsigs; 01095 } 01096 stats->sig_count += newsigs; 01097 stats->sig_reuse += reusedsigs; 01098 lock_basic_unlock(&stats->stats_lock); 01099 return ODS_STATUS_OK; 01100 } 01101 01102 01107 ods_status 01108 rrset_queue(rrset_type* rrset, fifoq_type* q, worker_type* worker) 01109 { 01110 ods_status status = ODS_STATUS_UNCHANGED; 01111 01112 if (!rrset) { 01113 ods_log_error("[%s] unable to queue RRset: no RRset", rrset_str); 01114 return ODS_STATUS_ASSERT_ERR; 01115 } 01116 ods_log_assert(rrset); 01117 if (!worker) { 01118 ods_log_error("[%s] unable to queue RRset: no worker", rrset_str); 01119 return ODS_STATUS_ASSERT_ERR; 01120 } 01121 ods_log_assert(worker); 01122 if (!q) { 01123 ods_log_error("[%s] unable to queue RRset: no queue", rrset_str); 01124 return ODS_STATUS_ASSERT_ERR; 01125 } 01126 ods_log_assert(q); 01127 01128 while (status == ODS_STATUS_UNCHANGED) { 01129 lock_basic_lock(&q->q_lock); 01130 status = fifoq_push(q, (void*) rrset, worker); 01131 lock_basic_unlock(&q->q_lock); 01132 } 01133 if (status == ODS_STATUS_OK) { 01134 lock_basic_lock(&worker->worker_lock); 01135 /* [LOCK] worker */ 01136 worker->jobs_appointed += 1; 01137 /* [UNLOCK] worker */ 01138 lock_basic_unlock(&worker->worker_lock); 01139 } 01140 return status; 01141 } 01142 01143 01148 void 01149 rrset_cleanup(rrset_type* rrset) 01150 { 01151 allocator_type* allocator; 01152 01153 if (!rrset) { 01154 return; 01155 } 01156 allocator = rrset->allocator; 01157 01158 if (rrset->rrs) { 01159 ldns_dnssec_rrs_deep_free(rrset->rrs); 01160 rrset->rrs = NULL; 01161 } 01162 if (rrset->add) { 01163 ldns_dnssec_rrs_deep_free(rrset->add); 01164 rrset->add = NULL; 01165 } 01166 if (rrset->del) { 01167 ldns_dnssec_rrs_deep_free(rrset->del); 01168 rrset->del = NULL; 01169 } 01170 if (rrset->rrsigs) { 01171 rrsigs_cleanup(rrset->rrsigs); 01172 rrset->rrsigs = NULL; 01173 } 01174 01175 allocator_deallocate(allocator, (void*) rrset); 01176 allocator_cleanup(allocator); 01177 return; 01178 } 01179 01180 01185 void 01186 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs) 01187 { 01188 if (!rrset || !fd) { 01189 return; 01190 } 01191 ods_log_assert(fd); 01192 ods_log_assert(rrset); 01193 01194 if (rrset->rrs) { 01195 if (rrset->rr_type == LDNS_RR_TYPE_CNAME || 01196 rrset->rr_type == LDNS_RR_TYPE_DNAME) { 01197 /* singleton types */ 01198 if (rrset->rrs->rr) { 01199 ldns_rr_print(fd, rrset->rrs->rr); 01200 } 01201 } else { 01202 ldns_dnssec_rrs_print(fd, rrset->rrs); 01203 } 01204 } 01205 if (rrset->rrsigs && !skip_rrsigs) { 01206 rrsigs_print(fd, rrset->rrsigs, 0); 01207 } 01208 return; 01209 } 01210 01211 01216 void 01217 rrset_backup(FILE* fd, rrset_type* rrset) 01218 { 01219 if (!rrset || !fd) { 01220 return; 01221 } 01222 if (rrset->rrsigs) { 01223 rrsigs_print(fd, rrset->rrsigs, 1); 01224 } 01225 return; 01226 }