⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnssec-signzone.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Portions Copyright (C) 1999-2001, 2003  Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM AND * NETWORK ASSOCIATES DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE CONSORTIUM OR NETWORK * ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: dnssec-signzone.c,v 1.139.2.2 2003/03/06 04:38:13 marka Exp $ */#include <config.h>#include <stdlib.h>#include <time.h>#include <isc/app.h>#include <isc/commandline.h>#include <isc/entropy.h>#include <isc/event.h>#include <isc/file.h>#include <isc/mem.h>#include <isc/mutex.h>#include <isc/os.h>#include <isc/stdio.h>#include <isc/string.h>#include <isc/task.h>#include <isc/util.h>#include <isc/time.h>#include <dns/db.h>#include <dns/dbiterator.h>#include <dns/diff.h>#include <dns/dnssec.h>#include <dns/fixedname.h>#include <dns/keyvalues.h>#include <dns/log.h>#include <dns/master.h>#include <dns/masterdump.h>#include <dns/nxt.h>#include <dns/rdata.h>#include <dns/rdataset.h>#include <dns/rdataclass.h>#include <dns/rdatasetiter.h>#include <dns/rdatastruct.h>#include <dns/rdatatype.h>#include <dns/result.h>#include <dns/secalg.h>#include <dns/time.h>#include <dst/dst.h>#include <dst/result.h>#include "dnssectool.h"const char *program = "dnssec-signzone";int verbose;#define BUFSIZE 2048typedef struct signer_key_struct signer_key_t;struct signer_key_struct {	dst_key_t *key;	isc_boolean_t isdefault;	unsigned int position;	ISC_LINK(signer_key_t) link;};#define SIGNER_EVENTCLASS	ISC_EVENTCLASS(0x4453)#define SIGNER_EVENT_WRITE	(SIGNER_EVENTCLASS + 0)#define SIGNER_EVENT_WORK	(SIGNER_EVENTCLASS + 1)typedef struct signer_event sevent_t;struct signer_event {	ISC_EVENT_COMMON(sevent_t);	dns_fixedname_t *fname;	dns_fixedname_t *fnextname;	dns_dbnode_t *node;};static ISC_LIST(signer_key_t) keylist;static unsigned int keycount = 0;static isc_stdtime_t starttime = 0, endtime = 0, now;static int cycle = -1;static isc_boolean_t tryverify = ISC_FALSE;static isc_boolean_t printstats = ISC_FALSE;static isc_mem_t *mctx = NULL;static isc_entropy_t *ectx = NULL;static dns_ttl_t zonettl;static FILE *fp;static char *tempfile = NULL;static const dns_master_style_t *masterstyle;static unsigned int nsigned = 0, nretained = 0, ndropped = 0;static unsigned int nverified = 0, nverifyfailed = 0;static const char *directory;static isc_mutex_t namelock, statslock;static isc_taskmgr_t *taskmgr = NULL;static dns_db_t *gdb;			/* The database */static dns_dbversion_t *gversion;	/* The database version */static dns_dbiterator_t *gdbiter;	/* The database iterator */static dns_name_t *gorigin;		/* The database origin */static dns_dbnode_t *gnode = NULL;	/* The "current" database node */static dns_name_t *lastzonecut;static isc_task_t *master = NULL;static unsigned int ntasks = 0;static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;static unsigned int assigned = 0, completed = 0;static isc_boolean_t nokeys = ISC_FALSE;static isc_boolean_t removefile = ISC_FALSE;#define INCSTAT(counter)		\	if (printstats) {		\		LOCK(&statslock);	\		counter++;		\		UNLOCK(&statslock);	\	}static voidsign(isc_task_t *task, isc_event_t *event);static inline voidset_bit(unsigned char *array, unsigned int index, unsigned int bit) {	unsigned int shift, mask;	shift = 7 - (index % 8);	mask = 1 << shift;	if (bit != 0)		array[index / 8] |= mask;	else		array[index / 8] &= (~mask & 0xFF);}static signer_key_t *newkeystruct(dst_key_t *dstkey, isc_boolean_t isdefault) {	signer_key_t *key;	key = isc_mem_get(mctx, sizeof(signer_key_t));	if (key == NULL)		fatal("out of memory");	key->key = dstkey;	key->isdefault = isdefault;	key->position = keycount++;	ISC_LINK_INIT(key, link);	return (key);}static voidsignwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdata_t *rdata,	    dst_key_t *key, isc_buffer_t *b){	isc_result_t result;	result = dns_dnssec_sign(name, rdataset, key, &starttime, &endtime,				 mctx, b, rdata);	isc_entropy_stopcallbacksources(ectx);	if (result != ISC_R_SUCCESS) {		char keystr[KEY_FORMATSIZE];		key_format(key, keystr, sizeof keystr);		fatal("key '%s' failed to sign data: %s",		      keystr, isc_result_totext(result));	}	INCSTAT(nsigned);	if (tryverify) {		result = dns_dnssec_verify(name, rdataset, key,					   ISC_TRUE, mctx, rdata);		if (result == ISC_R_SUCCESS) {			vbprintf(3, "\tsignature verified\n");			INCSTAT(nverified);		} else {			vbprintf(3, "\tsignature failed to verify\n");			INCSTAT(nverifyfailed);		}	}}static inline isc_boolean_tissigningkey(signer_key_t *key) {	return (key->isdefault);}static inline isc_boolean_tiszonekey(signer_key_t *key) {	return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&		       dst_key_iszonekey(key->key)));}/* * Finds the key that generated a SIG, if possible.  First look at the keys * that we've loaded already, and then see if there's a key on disk. */static signer_key_t *keythatsigned(dns_rdata_sig_t *sig) {	isc_result_t result;	dst_key_t *pubkey = NULL, *privkey = NULL;	signer_key_t *key;	key = ISC_LIST_HEAD(keylist);	while (key != NULL) {		if (sig->keyid == dst_key_id(key->key) &&		    sig->algorithm == dst_key_alg(key->key) &&		    dns_name_equal(&sig->signer, dst_key_name(key->key)))			return key;		key = ISC_LIST_NEXT(key, link);	}	result = dst_key_fromfile(&sig->signer, sig->keyid, sig->algorithm,				  DST_TYPE_PUBLIC, NULL, mctx, &pubkey);	if (result != ISC_R_SUCCESS)		return (NULL);	result = dst_key_fromfile(&sig->signer, sig->keyid, sig->algorithm,				  DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,				  NULL, mctx, &privkey);	if (result == ISC_R_SUCCESS) {		dst_key_free(&pubkey);		key = newkeystruct(privkey, ISC_FALSE);	} else		key = newkeystruct(pubkey, ISC_FALSE);	ISC_LIST_APPEND(keylist, key, link);	return (key);}/* * Check to see if we expect to find a key at this name.  If we see a SIG * and can't find the signing key that we expect to find, we drop the sig. * I'm not sure if this is completely correct, but it seems to work. */static isc_boolean_texpecttofindkey(dns_name_t *name) {	unsigned int options = DNS_DBFIND_NOWILD;	dns_fixedname_t fname;	isc_result_t result;	char namestr[DNS_NAME_FORMATSIZE];	dns_fixedname_init(&fname);	result = dns_db_find(gdb, name, gversion, dns_rdatatype_key, options,			     0, NULL, dns_fixedname_name(&fname), NULL, NULL);	switch (result) {	case ISC_R_SUCCESS:	case DNS_R_NXDOMAIN:	case DNS_R_NXRRSET:		return (ISC_TRUE);	case DNS_R_DELEGATION:	case DNS_R_CNAME:	case DNS_R_DNAME:		return (ISC_FALSE);	}	dns_name_format(name, namestr, sizeof namestr);	fatal("failure looking for '%s KEY' in database: %s",	      namestr, isc_result_totext(result));	return (ISC_FALSE); /* removes a warning */}static inline isc_boolean_tsetverifies(dns_name_t *name, dns_rdataset_t *set, signer_key_t *key,	    dns_rdata_t *sig){	isc_result_t result;	result = dns_dnssec_verify(name, set, key->key, ISC_FALSE, mctx, sig);	if (result == ISC_R_SUCCESS) {		INCSTAT(nverified);		return (ISC_TRUE);	} else {		INCSTAT(nverifyfailed);		return (ISC_FALSE);	}}/* * Signs a set.  Goes through contortions to decide if each SIG should * be dropped or retained, and then determines if any new SIGs need to * be generated. */static voidsignset(dns_diff_t *diff, dns_dbnode_t *node, dns_name_t *name,	dns_rdataset_t *set){	dns_rdataset_t sigset;	dns_rdata_t sigrdata = DNS_RDATA_INIT;	dns_rdata_sig_t sig;	signer_key_t *key;	isc_result_t result;	isc_boolean_t nosigs = ISC_FALSE;	isc_boolean_t *wassignedby, *nowsignedby;	int arraysize;	dns_difftuple_t *tuple;	dns_ttl_t ttl;	int i;	char namestr[DNS_NAME_FORMATSIZE];	char typestr[TYPE_FORMATSIZE];	char sigstr[SIG_FORMATSIZE];	dns_name_format(name, namestr, sizeof namestr);	type_format(set->type, typestr, sizeof typestr);	ttl = ISC_MIN(set->ttl, endtime - starttime);	dns_rdataset_init(&sigset);	result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_sig,				     set->type, 0, &sigset, NULL);	if (result == ISC_R_NOTFOUND) {		result = ISC_R_SUCCESS;		nosigs = ISC_TRUE;	}	if (result != ISC_R_SUCCESS)		fatal("failed while looking for '%s SIG %s': %s",		      namestr, typestr, isc_result_totext(result));	vbprintf(1, "%s/%s:\n", namestr, typestr);	arraysize = keycount;	if (!nosigs)		arraysize += dns_rdataset_count(&sigset);	wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));	nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));	if (wassignedby == NULL || nowsignedby == NULL)		fatal("out of memory");	for (i = 0; i < arraysize; i++)		wassignedby[i] = nowsignedby[i] = ISC_FALSE;	if (nosigs)		result = ISC_R_NOMORE;	else		result = dns_rdataset_first(&sigset);	while (result == ISC_R_SUCCESS) {		isc_boolean_t expired, future;		isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE;		dns_rdataset_current(&sigset, &sigrdata);		result = dns_rdata_tostruct(&sigrdata, &sig, NULL);		check_result(result, "dns_rdata_tostruct");		expired = ISC_TF(now + cycle > sig.timeexpire);		future = ISC_TF(now < sig.timesigned);		key = keythatsigned(&sig);		sig_format(&sig, sigstr, sizeof sigstr);		if (sig.timesigned > sig.timeexpire) {			/* sig is dropped and not replaced */			vbprintf(2, "\tsig by %s dropped - "				 "invalid validity period\n",				 sigstr);		} else if (key == NULL && !future &&			 expecttofindkey(&sig.signer))		{			/* sig is dropped and not replaced */			vbprintf(2, "\tsig by %s dropped - "				 "private key not found\n",				 sigstr);		} else if (key == NULL || future) {			vbprintf(2, "\tsig by %s %s - key not found\n",				 expired ? "retained" : "dropped", sigstr);			if (!expired)				keep = ISC_TRUE;		} else if (issigningkey(key)) {			if (!expired && setverifies(name, set, key, &sigrdata))			{				vbprintf(2, "\tsig by %s retained\n", sigstr);				keep = ISC_TRUE;				wassignedby[key->position] = ISC_TRUE;				nowsignedby[key->position] = ISC_TRUE;			} else {				vbprintf(2, "\tsig by %s dropped - %s\n",					 sigstr,					 expired ? "expired" :						   "failed to verify");				wassignedby[key->position] = ISC_TRUE;				resign = ISC_TRUE;			}		} else if (iszonekey(key)) {			if (!expired && setverifies(name, set, key, &sigrdata))			{				vbprintf(2, "\tsig by %s retained\n", sigstr);				keep = ISC_TRUE;				wassignedby[key->position] = ISC_TRUE;				nowsignedby[key->position] = ISC_TRUE;			} else {				vbprintf(2, "\tsig by %s dropped - %s\n",					 sigstr,					 expired ? "expired" :						   "failed to verify");				wassignedby[key->position] = ISC_TRUE;			}		} else if (!expired) {			vbprintf(2, "\tsig by %s retained\n", sigstr);			keep = ISC_TRUE;		} else {			vbprintf(2, "\tsig by %s expired\n", sigstr);		}		if (keep) {			nowsignedby[key->position] = ISC_TRUE;			INCSTAT(nretained);		} else {			tuple = NULL;			result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL,						      name, sigset.ttl,						      &sigrdata, &tuple);			check_result(result, "dns_difftuple_create");			dns_diff_append(diff, &tuple);			INCSTAT(ndropped);		}		if (resign) {			isc_buffer_t b;			dns_rdata_t trdata = DNS_RDATA_INIT;			unsigned char array[BUFSIZE];			char keystr[KEY_FORMATSIZE];			key_format(key->key, keystr, sizeof keystr);			vbprintf(1, "\tresigning with key %s\n", keystr);			isc_buffer_init(&b, array, sizeof(array));			signwithkey(name, set, &trdata, key->key, &b);			nowsignedby[key->position] = ISC_TRUE;			tuple = NULL;			result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,						      name, ttl, &trdata,						      &tuple);			check_result(result, "dns_difftuple_create");			dns_diff_append(diff, &tuple);		}		dns_rdata_reset(&sigrdata);		dns_rdata_freestruct(&sig);		result = dns_rdataset_next(&sigset);	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	check_result(result, "dns_rdataset_first/next");	if (dns_rdataset_isassociated(&sigset))		dns_rdataset_disassociate(&sigset);	key = ISC_LIST_HEAD(keylist);	while (key != NULL) {		if (key->isdefault && !nowsignedby[key->position]) {			isc_buffer_t b;			dns_rdata_t trdata = DNS_RDATA_INIT;			unsigned char array[BUFSIZE];			char keystr[KEY_FORMATSIZE];			key_format(key->key, keystr, sizeof keystr);			vbprintf(1, "\tsigning with key %s\n", keystr);			isc_buffer_init(&b, array, sizeof(array));			signwithkey(name, set, &trdata, key->key, &b);			tuple = NULL;			result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,						      name, ttl, &trdata,						      &tuple);			check_result(result, "dns_difftuple_create");			dns_diff_append(diff, &tuple);		}		key = ISC_LIST_NEXT(key, link);

⌨️ 快捷键说明

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