📄 dnssec-signzone.c
字号:
} isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t)); isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t));}/* Determine if a KEY set contains a null key */static isc_boolean_thasnullkey(dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t found = ISC_FALSE; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dst_key_t *key = NULL; dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); result = dns_dnssec_keyfromrdata(dns_rootname, &rdata, mctx, &key); if (result != ISC_R_SUCCESS) fatal("could not convert KEY into internal format: %s", isc_result_totext(result)); if (dst_key_isnullkey(key)) found = ISC_TRUE; dst_key_free(&key); if (found == ISC_TRUE) return (ISC_TRUE); result = dns_rdataset_next(rdataset); } if (result != ISC_R_NOMORE) fatal("failure looking for null keys"); return (ISC_FALSE);}static voidopendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp){ char filename[256]; isc_buffer_t b; isc_result_t result; isc_buffer_init(&b, filename, sizeof(filename)); if (directory != NULL) { isc_buffer_putstr(&b, directory); if (directory[strlen(directory) - 1] != '/') isc_buffer_putstr(&b, "/"); } isc_buffer_putstr(&b, prefix); result = dns_name_tofilenametext(name, ISC_FALSE, &b); check_result(result, "dns_name_tofilenametext()"); if (isc_buffer_availablelength(&b) == 0) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); fatal("name '%s' is too long", namestr); } isc_buffer_putuint8(&b, 0); result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, rdclass, 0, NULL, dbp); check_result(result, "dns_db_create()"); result = dns_db_load(*dbp, filename); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) dns_db_detach(dbp);}/* * Looks for signatures of the zone keys by the parent, and imports them * if found. */static voidimportparentsig(dns_diff_t *diff, dns_name_t *name, dns_rdataset_t *set) { dns_db_t *newdb = NULL; dns_dbnode_t *newnode = NULL; dns_rdataset_t newset, sigset; dns_rdata_t rdata = DNS_RDATA_INIT, newrdata = DNS_RDATA_INIT; isc_result_t result; dns_rdataset_init(&newset); dns_rdataset_init(&sigset); opendb("signedkey-", name, dns_db_class(gdb), &newdb); if (newdb == NULL) return; result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key, 0, 0, &newset, &sigset); if (result != ISC_R_SUCCESS) goto failure; if (!dns_rdataset_isassociated(&newset) || !dns_rdataset_isassociated(&sigset)) goto failure; if (dns_rdataset_count(set) != dns_rdataset_count(&newset)) { result = DNS_R_BADDB; goto failure; } result = dns_rdataset_first(set); check_result(result, "dns_rdataset_first()"); for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(set)) { dns_rdataset_current(set, &rdata); result = dns_rdataset_first(&newset); check_result(result, "dns_rdataset_first()"); for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&newset)) { dns_rdataset_current(&newset, &newrdata); if (dns_rdata_compare(&rdata, &newrdata) == 0) break; dns_rdata_reset(&newrdata); } dns_rdata_reset(&newrdata); dns_rdata_reset(&rdata); if (result != ISC_R_SUCCESS) break; } if (result != ISC_R_NOMORE) goto failure; vbprintf(2, "found the parent's signature of our zone key\n"); result = dns_rdataset_first(&sigset); while (result == ISC_R_SUCCESS) { dns_difftuple_t *tuple = NULL; dns_rdataset_current(&sigset, &rdata); result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, sigset.ttl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(diff, &tuple); result = dns_rdataset_next(&sigset); dns_rdata_reset(&rdata); } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; failure: if (dns_rdataset_isassociated(&newset)) dns_rdataset_disassociate(&newset); if (dns_rdataset_isassociated(&sigset)) dns_rdataset_disassociate(&sigset); if (newnode != NULL) dns_db_detachnode(newdb, &newnode); if (newdb != NULL) dns_db_detach(&newdb); if (result != ISC_R_SUCCESS) fatal("zone signedkey file is invalid or does not match zone");}/* * Looks for our signatures of child keys. If present, inform the caller. */static isc_boolean_thaschildkey(dns_name_t *name) { dns_db_t *newdb = NULL; dns_dbnode_t *newnode = NULL; dns_rdataset_t set, sigset; dns_rdata_t sigrdata = DNS_RDATA_INIT; isc_result_t result; isc_boolean_t found = ISC_FALSE; dns_rdata_sig_t sig; signer_key_t *key; dns_rdataset_init(&set); dns_rdataset_init(&sigset); opendb("signedkey-", name, dns_db_class(gdb), &newdb); if (newdb == NULL) return (ISC_FALSE); result = dns_db_findnode(newdb, name, ISC_FALSE, &newnode); if (result != ISC_R_SUCCESS) goto failure; result = dns_db_findrdataset(newdb, newnode, NULL, dns_rdatatype_key, 0, 0, &set, &sigset); if (result != ISC_R_SUCCESS) goto failure; if (!dns_rdataset_isassociated(&set) || !dns_rdataset_isassociated(&sigset)) goto failure; result = dns_rdataset_first(&sigset); check_result(result, "dns_rdataset_first()"); dns_rdata_init(&sigrdata); for (; result == ISC_R_SUCCESS; result = dns_rdataset_next(&sigset)) { dns_rdataset_current(&sigset, &sigrdata); result = dns_rdata_tostruct(&sigrdata, &sig, NULL); if (result != ISC_R_SUCCESS) goto failure; key = keythatsigned(&sig); dns_rdata_freestruct(&sig); if (key == NULL) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); fprintf(stderr, "creating KEY from signedkey file for %s: " "%s\n", namestr, isc_result_totext(result)); goto failure; } result = dns_dnssec_verify(name, &set, key->key, ISC_FALSE, mctx, &sigrdata); if (result == ISC_R_SUCCESS) { found = ISC_TRUE; break; } else { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); fprintf(stderr, "verifying SIG in signedkey file for %s: %s\n", namestr, isc_result_totext(result)); } dns_rdata_reset(&sigrdata); } failure: if (dns_rdataset_isassociated(&set)) dns_rdataset_disassociate(&set); if (dns_rdataset_isassociated(&sigset)) dns_rdataset_disassociate(&sigset); if (newnode != NULL) dns_db_detachnode(newdb, &newnode); if (newdb != NULL) dns_db_detach(&newdb); return (found);}/* * There probably should be a dns_nxt_setbit, but it can get complicated if * the length of the bit set needs to be increased. In this case, since the * NXT bit is set and both SIG and KEY are less than NXT, the easy way works. */static voidnxt_setbit(dns_rdataset_t *rdataset, dns_rdatatype_t type) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nxt_t nxt; result = dns_rdataset_first(rdataset); check_result(result, "dns_rdataset_first()"); dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nxt, NULL); check_result(result, "dns_rdata_tostruct"); set_bit(nxt.typebits, type, 1); dns_rdata_freestruct(&nxt);}static voidcreatenullkey(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, dns_ttl_t ttl){ unsigned char keydata[4]; dns_rdata_t keyrdata = DNS_RDATA_INIT; dns_rdata_key_t key; dns_diff_t diff; dns_difftuple_t *tuple = NULL; isc_buffer_t b; isc_result_t result; char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); vbprintf(2, "adding null key at %s\n", namestr); key.common.rdclass = dns_db_class(db); key.common.rdtype = dns_rdatatype_key; ISC_LINK_INIT(&key.common, link); key.mctx = NULL; key.flags = DNS_KEYTYPE_NOKEY | DNS_KEYOWNER_ZONE; key.protocol = DNS_KEYPROTO_DNSSEC; key.algorithm = DNS_KEYALG_DSA; key.datalen = 0; key.data = NULL; isc_buffer_init(&b, keydata, sizeof keydata); result = dns_rdata_fromstruct(&keyrdata, dns_db_class(db), dns_rdatatype_key, &key, &b); if (result != ISC_R_SUCCESS) fatal("failed to build null key"); dns_diff_init(mctx, &diff); result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &keyrdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff);}/* * Signs all records at a name. This mostly just signs each set individually, * but also adds the SIG bit to any NXTs generated earlier, deals with * parent/child KEY signatures, and handles other exceptional cases. */static voidsignname(dns_dbnode_t *node, dns_name_t *name) { isc_result_t result; dns_rdataset_t rdataset; dns_rdatasetiter_t *rdsiter; isc_boolean_t isdelegation = ISC_FALSE; isc_boolean_t childkey = ISC_FALSE; static int warnwild = 0; isc_boolean_t atorigin; isc_boolean_t neednullkey = ISC_FALSE; dns_diff_t diff; if (dns_name_iswildcard(name)) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); if (warnwild++ == 0) { fprintf(stderr, "%s: warning: BIND 9 doesn't properly " "handle wildcards in secure zones:\n", program); fprintf(stderr, "\t- wildcard nonexistence proof is " "not generated by the server\n"); fprintf(stderr, "\t- wildcard nonexistence proof is " "not required by the resolver\n"); } fprintf(stderr, "%s: warning: wildcard name seen: %s\n", program, namestr); } atorigin = dns_name_equal(name, gorigin); /* * If this is not the origin, determine if it's a delegation point. */ if (!atorigin) { dns_rdataset_t nsset; dns_rdataset_init(&nsset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns, 0, 0, &nsset, NULL); /* Is this a delegation point? */ if (result == ISC_R_SUCCESS) { isdelegation = ISC_TRUE; dns_rdataset_disassociate(&nsset); } } /* * If this is a delegation point, determine if we need to generate * a null key. */ if (isdelegation) { dns_rdataset_t keyset; dns_ttl_t nullkeyttl; childkey = haschildkey(name); neednullkey = ISC_TRUE; nullkeyttl = zonettl; dns_rdataset_init(&keyset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_key, 0, 0, &keyset, NULL); if (result == ISC_R_SUCCESS && childkey) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); if (hasnullkey(&keyset)) { fatal("%s has both a signedkey file and " "null keys in the zone. Aborting.", namestr); } vbprintf(2, "child key for %s found\n", namestr); neednullkey = ISC_FALSE; dns_rdataset_disassociate(&keyset); } else if (result == ISC_R_SUCCESS) { if (hasnullkey(&keyset)) neednullkey = ISC_FALSE; nullkeyttl = keyset.ttl; dns_rdataset_disassociate(&keyset); } else if (childkey) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); vbprintf(2, "child key for %s found\n", namestr); neednullkey = ISC_FALSE; } if (neednullkey) createnullkey(gdb, gversion, name, nullkeyttl); } /* * Now iterate through the rdatasets. */ dns_diff_init(mctx, &diff); dns_rdataset_init(&rdataset); rdsiter = NULL; result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); /* If this is a SIG set, skip it. */ if (rdataset.type == dns_rdatatype_sig) goto skip; /* * If this is a KEY set at the apex, look for a signedkey file. */ if (atorigin && rdataset.type == dns_rdatatype_key) { importparentsig(&diff, name, &rdataset); goto skip; } /* * If this name is a delegation point, skip all records * except an NXT set a KEY set containing a null key. */ if (isdelegation) { if (!(rdataset.type == dns_rdatatype_nxt || (rdataset.type == dns_rdatatype_key && hasnullkey(&rdataset)))) goto skip; } if (rdataset.type == dns_rdatatype_nxt) { if (!nokeys) nxt_setbit(&rdataset, dns_rdatatype_sig); if (neednullkey) nxt_setbit(&rdataset, dns_rdatatype_key); } signset(&diff, node, name, &rdataset); skip: dns_rdataset_disassociate(&rdataset); result = dns_rdatasetiter_next(rdsiter); } if (result != ISC_R_NOMORE) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); fatal("rdataset iteration for name '%s' failed: %s", namestr, isc_result_totext(result)); } dns_rdatasetiter_destroy(&rdsiter); result = dns_diff_apply(&diff, gdb, gversion); if (result != ISC_R_SUCCESS) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof namestr); fatal("failed to add SIGs at node '%s': %s", namestr, isc_result_totext(result)); } dns_diff_clear(&diff);}static inline isc_boolean_tactive_node(dns_dbnode_t *node) { dns_rdatasetiter_t *rdsiter; isc_boolean_t active = ISC_FALSE; isc_result_t result; dns_rdataset_t rdataset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -