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