dnssec-signzone.c

来自「非常好的dns解析软件」· C语言 代码 · 共 2,334 行 · 第 1/5 页

C
2,334
字号
	dns_rdataset_init(&rdataset);	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 (rdataset.type != dns_rdatatype_nsec &&		    rdataset.type != dns_rdatatype_rrsig)			active = ISC_TRUE;		dns_rdataset_disassociate(&rdataset);		if (!active)			result = dns_rdatasetiter_next(rdsiter);		else			result = ISC_R_NOMORE;	}	if (result != ISC_R_NOMORE)		fatal("rdataset iteration failed: %s",		      isc_result_totext(result));	if (!active) {		/*%		 * The node is empty of everything but NSEC / RRSIG records.		 */		for (result = dns_rdatasetiter_first(rdsiter);		     result == ISC_R_SUCCESS;		     result = dns_rdatasetiter_next(rdsiter)) {			dns_rdatasetiter_current(rdsiter, &rdataset);			result = dns_db_deleterdataset(gdb, node, gversion,						       rdataset.type,						       rdataset.covers);			check_result(result, "dns_db_deleterdataset()");			dns_rdataset_disassociate(&rdataset);		}		if (result != ISC_R_NOMORE)			fatal("rdataset iteration failed: %s",			      isc_result_totext(result));	} else {		/* 		 * Delete RRSIGs for types that no longer exist.		 */		result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2);		check_result(result, "dns_db_allrdatasets()");		for (result = dns_rdatasetiter_first(rdsiter);		     result == ISC_R_SUCCESS;		     result = dns_rdatasetiter_next(rdsiter)) {			dns_rdatasetiter_current(rdsiter, &rdataset);			type = rdataset.type;			covers = rdataset.covers;			dns_rdataset_disassociate(&rdataset);			if (type != dns_rdatatype_rrsig)				continue;			found = ISC_FALSE;			for (result = dns_rdatasetiter_first(rdsiter2);			     !found && result == ISC_R_SUCCESS;			     result = dns_rdatasetiter_next(rdsiter2)) {				dns_rdatasetiter_current(rdsiter2, &rdataset);				if (rdataset.type == covers)					found = ISC_TRUE;				dns_rdataset_disassociate(&rdataset);			}			if (!found) {				if (result != ISC_R_NOMORE)					fatal("rdataset iteration failed: %s",					      isc_result_totext(result));				result = dns_db_deleterdataset(gdb, node,							       gversion, type,							       covers);				check_result(result,					     "dns_db_deleterdataset(rrsig)");			} else if (result != ISC_R_NOMORE &&				   result != ISC_R_SUCCESS)				fatal("rdataset iteration failed: %s",				      isc_result_totext(result));		}		if (result != ISC_R_NOMORE)			fatal("rdataset iteration failed: %s",			      isc_result_totext(result));		dns_rdatasetiter_destroy(&rdsiter2);	}	dns_rdatasetiter_destroy(&rdsiter);	return (active);}/*% * Extracts the TTL from the SOA. */static dns_ttl_tsoattl(void) {	dns_rdataset_t soaset;	dns_fixedname_t fname;	dns_name_t *name;	isc_result_t result;	dns_ttl_t ttl;	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_rdata_soa_t soa;	dns_fixedname_init(&fname);	name = dns_fixedname_name(&fname);	dns_rdataset_init(&soaset);	result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa,			     0, 0, NULL, name, &soaset, NULL);	if (result != ISC_R_SUCCESS)		fatal("failed to find an SOA at the zone apex: %s",		      isc_result_totext(result));	result = dns_rdataset_first(&soaset);	check_result(result, "dns_rdataset_first");	dns_rdataset_current(&soaset, &rdata);	result = dns_rdata_tostruct(&rdata, &soa, NULL);	check_result(result, "dns_rdata_tostruct");	ttl = soa.minimum;	dns_rdataset_disassociate(&soaset);	return (ttl);}/*% * Increment (or set if nonzero) the SOA serial */static isc_result_tsetsoaserial(isc_uint32_t serial) {	isc_result_t result;	dns_dbnode_t *node = NULL;	dns_rdataset_t rdataset;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_uint32_t old_serial, new_serial;	result = dns_db_getoriginnode(gdb, &node);	if (result != ISC_R_SUCCESS)		return result;	dns_rdataset_init(&rdataset);	result = dns_db_findrdataset(gdb, node, gversion,				     dns_rdatatype_soa, 0,				     0, &rdataset, NULL);	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_rdataset_first(&rdataset);	RUNTIME_CHECK(result == ISC_R_SUCCESS);	dns_rdataset_current(&rdataset, &rdata);	old_serial = dns_soa_getserial(&rdata);	if (serial) {		/* Set SOA serial to the value provided. */		new_serial = serial;	} else {		/* Increment SOA serial using RFC 1982 arithmetics */		new_serial = (old_serial + 1) & 0xFFFFFFFF;		if (new_serial == 0)			new_serial = 1;	}	/* If the new serial is not likely to cause a zone transfer	 * (a/ixfr) from servers having the old serial, warn the user.	 *	 * RFC1982 section 7 defines the maximum increment to be	 * (2^(32-1))-1.  Using u_int32_t arithmetic, we can do a single	 * comparison.  (5 - 6 == (2^32)-1, not negative-one)	 */	if (new_serial == old_serial ||	    (new_serial - old_serial) > 0x7fffffffU)		fprintf(stderr, "%s: warning: Serial number not advanced, "			"zone may not transfer\n", program);	dns_soa_setserial(new_serial, &rdata);	result = dns_db_deleterdataset(gdb, node, gversion,				       dns_rdatatype_soa, 0);	check_result(result, "dns_db_deleterdataset");	if (result != ISC_R_SUCCESS)		goto cleanup;	result = dns_db_addrdataset(gdb, node, gversion,				    0, &rdataset, 0, NULL);	check_result(result, "dns_db_addrdataset");	if (result != ISC_R_SUCCESS)		goto cleanup;cleanup:	dns_rdataset_disassociate(&rdataset);	if (node != NULL)		dns_db_detachnode(gdb, &node);	dns_rdata_reset(&rdata);	return (result);}/*% * Delete any RRSIG records at a node. */static voidcleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {	dns_rdatasetiter_t *rdsiter = NULL;	dns_rdataset_t set;	isc_result_t result, dresult;	if (outputformat != dns_masterformat_text)		return;	dns_rdataset_init(&set);	result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);	check_result(result, "dns_db_allrdatasets");	result = dns_rdatasetiter_first(rdsiter);	while (result == ISC_R_SUCCESS) {		isc_boolean_t destroy = ISC_FALSE;		dns_rdatatype_t covers = 0;		dns_rdatasetiter_current(rdsiter, &set);		if (set.type == dns_rdatatype_rrsig) {			covers = set.covers;			destroy = ISC_TRUE;		}		dns_rdataset_disassociate(&set);		result = dns_rdatasetiter_next(rdsiter);		if (destroy) {			dresult = dns_db_deleterdataset(db, node, version,							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);}/*% * Sign the apex of the zone. */static voidsignapex(void) {	dns_dbnode_t *node = NULL;	dns_fixedname_t fixed;	dns_name_t *name;	isc_result_t result;		dns_fixedname_init(&fixed);	name = dns_fixedname_name(&fixed);	result = dns_dbiterator_current(gdbiter, &node, name);	check_result(result, "dns_dbiterator_current()");	signname(node, name);	dumpnode(name, node);	cleannode(gdb, gversion, node);	dns_db_detachnode(gdb, &node);	result = dns_dbiterator_next(gdbiter);	if (result == ISC_R_NOMORE)		finished = ISC_TRUE;	else if (result != ISC_R_SUCCESS)		fatal("failure iterating database: %s",		      isc_result_totext(result));}/*% * 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 (!dns_name_issubdomain(nextname, gorigin) ||			    (zonecut != NULL &&			     dns_name_issubdomain(nextname, zonecut)))			{				dns_db_detachnode(gdb, &nextnode);				result = dns_dbiterator_next(dbiter);				continue;			}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?