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