📄 dnssec-signzone.c
字号:
dns_rdatatype_rrsig, covers); check_result(dresult, "dns_db_deleterdataset"); } } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter);}/* * Set up the iterator and global state before starting the tasks. */static voidpresign(void) { isc_result_t result; gdbiter = NULL; result = dns_db_createiterator(gdb, ISC_FALSE, &gdbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(gdbiter); check_result(result, "dns_dbiterator_first()");}/* * Clean up the iterator and global state after the tasks complete. */static voidpostsign(void) { dns_dbiterator_destroy(&gdbiter);}/* * Assigns a node to a worker thread. This is protected by the master task's * lock. */static voidassignwork(isc_task_t *task, isc_task_t *worker) { dns_fixedname_t *fname; dns_name_t *name; dns_dbnode_t *node; sevent_t *sevent; dns_rdataset_t nsec; isc_boolean_t found; isc_result_t result; if (shuttingdown) return; if (finished) { if (assigned == completed) { isc_task_detach(&task); isc_app_shutdown(); } return; } fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); if (fname == NULL) fatal("out of memory"); dns_fixedname_init(fname); name = dns_fixedname_name(fname); node = NULL; found = ISC_FALSE; LOCK(&namelock); while (!found) { result = dns_dbiterator_current(gdbiter, &node, name); if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); dns_rdataset_init(&nsec); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec, 0, 0, &nsec, NULL); if (result == ISC_R_SUCCESS) found = ISC_TRUE; else dumpnode(name, node); if (dns_rdataset_isassociated(&nsec)) dns_rdataset_disassociate(&nsec); if (!found) dns_db_detachnode(gdb, &node); result = dns_dbiterator_next(gdbiter); if (result == ISC_R_NOMORE) { finished = ISC_TRUE; break; } else if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); } UNLOCK(&namelock); if (!found) { if (assigned == completed) { isc_task_detach(&task); isc_app_shutdown(); } isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); return; } sevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, sign, NULL, sizeof(sevent_t)); if (sevent == NULL) fatal("failed to allocate event\n"); sevent->node = node; sevent->fname = fname; isc_task_send(worker, ISC_EVENT_PTR(&sevent)); assigned++;}/* * Start a worker task */static voidstartworker(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; worker = (isc_task_t *)event->ev_arg; assignwork(task, worker); isc_event_free(&event);}/* * Write a node to the output file, and restart the worker task. */static voidwritenode(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; sevent_t *sevent = (sevent_t *)event; completed++; worker = (isc_task_t *)event->ev_sender; dumpnode(dns_fixedname_name(sevent->fname), sevent->node); cleannode(gdb, gversion, sevent->node); dns_db_detachnode(gdb, &sevent->node); isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); assignwork(task, worker); isc_event_free(&event);}/* * Sign a database node. */static voidsign(isc_task_t *task, isc_event_t *event) { dns_fixedname_t *fname; dns_dbnode_t *node; sevent_t *sevent, *wevent; sevent = (sevent_t *)event; node = sevent->node; fname = sevent->fname; isc_event_free(&event); signname(node, dns_fixedname_name(fname)); wevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, writenode, NULL, sizeof(sevent_t)); if (wevent == NULL) fatal("failed to allocate event\n"); wevent->node = node; wevent->fname = fname; isc_task_send(master, ISC_EVENT_PTR(&wevent));}/* * Generate NSEC records for the zone. */static voidnsecify(void) { dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; isc_boolean_t done = ISC_FALSE; isc_result_t result; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); dns_fixedname_init(&fzonecut); zonecut = NULL; result = dns_db_createiterator(gdb, ISC_FALSE, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { dns_dbiterator_current(dbiter, &node, name); if (delegation(name, node, NULL)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); } result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { isc_boolean_t active = ISC_FALSE; result = dns_dbiterator_current(dbiter, &nextnode, nextname); if (result != ISC_R_SUCCESS) break; active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (result != ISC_R_SUCCESS) { dns_db_detachnode(gdb, &nextnode); break; } if (!dns_name_issubdomain(nextname, gorigin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } dns_db_detachnode(gdb, &nextnode); break; } if (result == ISC_R_NOMORE) { dns_name_clone(gorigin, nextname); done = ISC_TRUE; } else if (result != ISC_R_SUCCESS) fatal("iterating through the database failed: %s", isc_result_totext(result)); result = dns_nsec_build(gdb, gversion, node, nextname, zonettl); check_result(result, "dns_nsec_build()"); dns_db_detachnode(gdb, &node); } dns_dbiterator_destroy(&dbiter);}/* * Load the zone file from disk */static voidloadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) { isc_buffer_t b; int len; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; len = strlen(origin); isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) fatal("failed converting name '%s' to dns format: %s", origin, isc_result_totext(result)); result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone, rdclass, 0, NULL, db); check_result(result, "dns_db_create()"); result = dns_db_load(*db, file); if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) fatal("failed loading zone from '%s': %s", file, isc_result_totext(result));}/* * Finds all public zone keys in the zone, and attempts to load the * private keys from disk. */static voidloadzonekeys(dns_db_t *db) { dns_dbnode_t *node; dns_dbversion_t *currentversion; isc_result_t result; dst_key_t *keys[20]; unsigned int nkeys, i; currentversion = NULL; dns_db_currentversion(db, ¤tversion); node = NULL; result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); result = dns_dnssec_findzonekeys(db, currentversion, node, gorigin, mctx, 20, keys, &nkeys); if (result == ISC_R_NOTFOUND) result = ISC_R_SUCCESS; if (result != ISC_R_SUCCESS) fatal("failed to find the zone keys: %s", isc_result_totext(result)); for (i = 0; i < nkeys; i++) { signer_key_t *key; key = newkeystruct(keys[i], ISC_TRUE); ISC_LIST_APPEND(keylist, key, link); } dns_db_detachnode(db, &node); dns_db_closeversion(db, ¤tversion, ISC_FALSE);}/* * Finds all public zone keys in the zone. */static voidloadzonepubkeys(dns_db_t *db) { dns_dbversion_t *currentversion = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dst_key_t *pubkey; signer_key_t *key; isc_result_t result; dns_db_currentversion(db, ¤tversion); result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, currentversion, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) fatal("failed to find keys at the zone apex: %s", isc_result_totext(result)); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { pubkey = NULL; dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx, &pubkey); if (result != ISC_R_SUCCESS) goto next; if (!dst_key_iszonekey(pubkey)) { dst_key_free(&pubkey); goto next; } key = newkeystruct(pubkey, ISC_FALSE); ISC_LIST_APPEND(keylist, key, link); next: result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); dns_db_closeversion(db, ¤tversion, ISC_FALSE);}static voidwarnifallksk(dns_db_t *db) { dns_dbversion_t *currentversion = NULL; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; dst_key_t *pubkey; isc_result_t result; dns_rdata_key_t key; isc_boolean_t have_non_ksk = ISC_FALSE; dns_db_currentversion(db, ¤tversion); result = dns_db_findnode(db, gorigin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) fatal("failed to find the zone's origin: %s", isc_result_totext(result)); dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, currentversion, dns_rdatatype_dnskey, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) fatal("failed to find keys at the zone apex: %s", isc_result_totext(result)); result = dns_rdataset_first(&rdataset); check_result(result, "dns_rdataset_first"); while (result == ISC_R_SUCCESS) { pubkey = NULL; dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &key, NULL); check_result(result, "dns_rdata_tostruct"); if ((key.flags & DNS_KEYFLAG_KSK) == 0) { have_non_ksk = ISC_TRUE; result = ISC_R_NOMORE; } else result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); dns_db_detachnode(db, &node); dns_db_closeversion(db, ¤tversion, ISC_FALSE); if (!have_non_ksk && !ignoreksk) fprintf(stderr, "%s: warning: No non-KSK dnskey found. " "Supply non-KSK dnskey or use '-z'.\n", program);}static voidwriteset(const char *prefix, dns_rdatatype_t type) { char *filename; char namestr[DNS_NAME_FORMATSIZE]; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; dns_diff_t diff; dns_difftuple_t *tuple = NULL; dns_fixedname_t fixed; dns_name_t *name; dns_rdata_t rdata, ds; isc_boolean_t have_ksk = ISC_FALSE; isc_boolean_t have_non_ksk = ISC_FALSE; isc_buffer_t b; isc_buffer_t namebuf; isc_region_t r; isc_result_t result; signer_key_t *key; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; unsigned char keybuf[DST_KEY_MAXSIZE]; unsigned int filenamelen; const dns_master_style_t *style = (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle; isc_buffer_init(&namebuf, namestr, sizeof(namestr)); result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf); check_result(result, "dns_name_tofilenametext"); isc_buffer_putuint8(&namebuf, 0); filenamelen = strlen(prefix) + strlen(namestr); if (directory != NULL) filenamelen += strlen(directory) + 1; filename = isc_mem_get(mctx, filenamelen + 1); if (filename == NULL) fatal("out of memory"); if (directory != NULL) sprintf(filename, "%s/", directory); else filename[0] = 0; strcat(filename, prefix); strcat(filename, namestr); dns_diff_init(mctx, &diff); for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) if (!key->isksk) { have_non_ksk = ISC_TRUE; break; } for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) if (key->isksk) { have_ksk = ISC_TRUE; break; } if (type == dns_rdatatype_dlv) { dns_name_t tname; unsigned int labels; dns_name_init(&tname, NULL); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); labels = dns_name_countlabels(gorigin); dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname); result = dns_name_concatenate(&tname, dlv, name, NULL); check_result(result, "dns_name_concatenate"); } else name = gorigin; for (key = ISC_LIST_HEAD(keylist); key != NULL; key = ISC_LIST_NEXT(key, link)) { if (have_ksk && have_non_ksk && !key->isksk) continue; dns_rdata_init(&rdata); dns_rdata_init(&ds); isc_buffer_init(&b, keybuf, sizeof(keybuf)); result = dst_key_todns(key->key, &b); check_result(result, "dst_key_todns"); isc_buffer_usedregion(&b, &r); dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r); if (type != dns_rdatatype_dnskey) { result = dns_ds_buildrdata(gorigin, &rdata, DNS_DSDIGEST_SHA1, dsbuf, &ds); check_result(result, "dns_ds_buildrdata"); if (type == dns_rdatatype_dlv) ds.type = dns_rdatatype_dlv; result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, 0, &ds, &tuple); } else result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, gorigin, zonettl, &rdata, &tuple); check_result(result, "dns_difftuple_create"); dns_diff_append(&diff, &tuple); } result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone, gclass, 0, NULL, &db); check_result(result, "dns_db_create"); result = dns_db_newversion(db, &version); check_result(result, "dns_db_newversion"); result = dns_diff_apply(&diff, db, version); check_result(result, "dns_diff_apply"); dns_diff_clear(&diff);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -