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

📄 tkey.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003  Internet Software Consortium. * * 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 ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC 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: tkey.c,v 1.71.2.1.10.5 2004/06/11 00:30:54 marka Exp $ */#include <config.h>#include <isc/buffer.h>#include <isc/entropy.h>#include <isc/md5.h>#include <isc/mem.h>#include <isc/string.h>#include <isc/util.h>#include <dns/dnssec.h>#include <dns/fixedname.h>#include <dns/keyvalues.h>#include <dns/log.h>#include <dns/message.h>#include <dns/name.h>#include <dns/rdata.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatastruct.h>#include <dns/result.h>#include <dns/tkey.h>#include <dns/tsig.h>#include <dst/dst.h>#include <dst/gssapi.h>#define TKEY_RANDOM_AMOUNT 16#define RETERR(x) do { \	result = (x); \	if (result != ISC_R_SUCCESS) \		goto failure; \	} while (0)static voidtkey_log(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2);static voidtkey_log(const char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL,		       DNS_LOGMODULE_REQUEST, ISC_LOG_DEBUG(4), fmt, ap);	va_end(ap);}isc_result_tdns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp){	dns_tkeyctx_t *tctx;	REQUIRE(mctx != NULL);	REQUIRE(ectx != NULL);	REQUIRE(tctxp != NULL && *tctxp == NULL);	tctx = isc_mem_get(mctx, sizeof(dns_tkeyctx_t));	if (tctx == NULL)		return (ISC_R_NOMEMORY);	tctx->mctx = NULL;	isc_mem_attach(mctx, &tctx->mctx);	tctx->ectx = NULL;	isc_entropy_attach(ectx, &tctx->ectx);	tctx->dhkey = NULL;	tctx->domain = NULL;	tctx->gsscred = NULL;	*tctxp = tctx;	return (ISC_R_SUCCESS);}voiddns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) {	isc_mem_t *mctx;	dns_tkeyctx_t *tctx;	REQUIRE(tctxp != NULL && *tctxp != NULL);	tctx = *tctxp;	mctx = tctx->mctx;	if (tctx->dhkey != NULL)		dst_key_free(&tctx->dhkey);	if (tctx->domain != NULL) {		if (dns_name_dynamic(tctx->domain))			dns_name_free(tctx->domain, mctx);		isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t));	}	isc_entropy_detach(&tctx->ectx);	isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t));	isc_mem_detach(&mctx);	*tctxp = NULL;}static isc_result_tadd_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata,		isc_uint32_t ttl, dns_namelist_t *namelist){	isc_result_t result;	isc_region_t r, newr;	dns_rdata_t *newrdata = NULL;	dns_name_t *newname = NULL;	dns_rdatalist_t *newlist = NULL;	dns_rdataset_t *newset = NULL;	isc_buffer_t *tmprdatabuf = NULL;	RETERR(dns_message_gettemprdata(msg, &newrdata));	dns_rdata_toregion(rdata, &r);	RETERR(isc_buffer_allocate(msg->mctx, &tmprdatabuf, r.length));	isc_buffer_availableregion(tmprdatabuf, &newr);	memcpy(newr.base, r.base, r.length);	dns_rdata_fromregion(newrdata, rdata->rdclass, rdata->type, &newr);	dns_message_takebuffer(msg, &tmprdatabuf);	RETERR(dns_message_gettempname(msg, &newname));	dns_name_init(newname, NULL);	RETERR(dns_name_dup(name, msg->mctx, newname));	RETERR(dns_message_gettemprdatalist(msg, &newlist));	newlist->rdclass = newrdata->rdclass;	newlist->type = newrdata->type;	newlist->covers = 0;	newlist->ttl = ttl;	ISC_LIST_INIT(newlist->rdata);	ISC_LIST_APPEND(newlist->rdata, newrdata, link);	RETERR(dns_message_gettemprdataset(msg, &newset));	dns_rdataset_init(newset);	RETERR(dns_rdatalist_tordataset(newlist, newset));	ISC_LIST_INIT(newname->list);	ISC_LIST_APPEND(newname->list, newset, link);	ISC_LIST_APPEND(*namelist, newname, link);	return (ISC_R_SUCCESS); failure:	if (newrdata != NULL) {		if (ISC_LINK_LINKED(newrdata, link))			ISC_LIST_UNLINK(newlist->rdata, newrdata, link);		dns_message_puttemprdata(msg, &newrdata);	}	if (newname != NULL)		dns_message_puttempname(msg, &newname);	if (newset != NULL) {		dns_rdataset_disassociate(newset);		dns_message_puttemprdataset(msg, &newset);	}	if (newlist != NULL)		dns_message_puttemprdatalist(msg, &newlist);	return (result);}static voidfree_namelist(dns_message_t *msg, dns_namelist_t *namelist) {	dns_name_t *name;	dns_rdataset_t *set;	while (!ISC_LIST_EMPTY(*namelist)) {		name = ISC_LIST_HEAD(*namelist);		ISC_LIST_UNLINK(*namelist, name, link);		while (!ISC_LIST_EMPTY(name->list)) {			set = ISC_LIST_HEAD(name->list);			ISC_LIST_UNLINK(name->list, set, link);			dns_message_puttemprdataset(msg, &set);		}		dns_message_puttempname(msg, &name);	}}static isc_result_tcompute_secret(isc_buffer_t *shared, isc_region_t *queryrandomness,	       isc_region_t *serverrandomness, isc_buffer_t *secret){	isc_md5_t md5ctx;	isc_region_t r, r2;	unsigned char digests[32];	unsigned int i;	isc_buffer_usedregion(shared, &r);	/*	 * MD5 ( query data | DH value ).	 */	isc_md5_init(&md5ctx);	isc_md5_update(&md5ctx, queryrandomness->base,		       queryrandomness->length);	isc_md5_update(&md5ctx, r.base, r.length);	isc_md5_final(&md5ctx, digests);	/*	 * MD5 ( server data | DH value ).	 */	isc_md5_init(&md5ctx);	isc_md5_update(&md5ctx, serverrandomness->base,		       serverrandomness->length);	isc_md5_update(&md5ctx, r.base, r.length);	isc_md5_final(&md5ctx, &digests[ISC_MD5_DIGESTLENGTH]);	/*	 * XOR ( DH value, MD5-1 | MD5-2).	 */	isc_buffer_availableregion(secret, &r);	isc_buffer_usedregion(shared, &r2);	if (r.length < sizeof(digests) || r.length < r2.length)		return (ISC_R_NOSPACE);	if (r2.length > sizeof(digests)) {		memcpy(r.base, r2.base, r2.length);		for (i = 0; i < sizeof(digests); i++)			r.base[i] ^= digests[i];		isc_buffer_add(secret, r2.length);	} else {		memcpy(r.base, digests, sizeof(digests));		for (i = 0; i < r2.length; i++)			r.base[i] ^= r2.base[i];		isc_buffer_add(secret, sizeof(digests));	}	return (ISC_R_SUCCESS);}static isc_result_tprocess_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,	       dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx,	       dns_rdata_tkey_t *tkeyout,	       dns_tsig_keyring_t *ring, dns_namelist_t *namelist){	isc_result_t result = ISC_R_SUCCESS;	dns_name_t *keyname, ourname;	dns_rdataset_t *keyset = NULL;	dns_rdata_t keyrdata = DNS_RDATA_INIT, ourkeyrdata = DNS_RDATA_INIT;	isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;	dst_key_t *pubkey = NULL;	isc_buffer_t ourkeybuf, *shared = NULL;	isc_region_t r, r2, ourkeyr;	unsigned char keydata[DST_KEY_MAXSIZE];	unsigned int sharedsize;	isc_buffer_t secret;	unsigned char *randomdata = NULL, secretdata[256];	dns_ttl_t ttl = 0;	if (tctx->dhkey == NULL) {		tkey_log("process_dhtkey: tkey-dhkey not defined");		tkeyout->error = dns_tsigerror_badalg;		return (DNS_R_REFUSED);	}	if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_HMACMD5_NAME)) {		tkey_log("process_dhtkey: algorithms other than "			 "hmac-md5 are not supported");		tkeyout->error = dns_tsigerror_badalg;		return (ISC_R_SUCCESS);	}	/*	 * Look for a DH KEY record that will work with ours.	 */	for (result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);	     result == ISC_R_SUCCESS && !found_key;	     result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL))	{		keyname = NULL;		dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);		keyset = NULL;		result = dns_message_findtype(keyname, dns_rdatatype_key, 0,					      &keyset);		if (result != ISC_R_SUCCESS)			continue;		for (result = dns_rdataset_first(keyset);		     result == ISC_R_SUCCESS && !found_key;		     result = dns_rdataset_next(keyset))		{			dns_rdataset_current(keyset, &keyrdata);			pubkey = NULL;			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,							 msg->mctx, &pubkey);			if (result != ISC_R_SUCCESS) {				dns_rdata_reset(&keyrdata);				continue;			}			if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {				if (dst_key_paramcompare(pubkey, tctx->dhkey))				{					found_key = ISC_TRUE;					ttl = keyset->ttl;					break;				} else					found_incompatible = ISC_TRUE;			}			dst_key_free(&pubkey);			dns_rdata_reset(&keyrdata);		}	}	if (!found_key) {		if (found_incompatible) {			tkey_log("process_dhtkey: found an incompatible key");			tkeyout->error = dns_tsigerror_badkey;			return (ISC_R_SUCCESS);		} else {			tkey_log("process_dhtkey: failed to find a key");			return (DNS_R_FORMERR);		}	}	RETERR(add_rdata_to_list(msg, keyname, &keyrdata, ttl, namelist));	isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata));	RETERR(dst_key_todns(tctx->dhkey, &ourkeybuf));	isc_buffer_usedregion(&ourkeybuf, &ourkeyr);	dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_any,			     dns_rdatatype_key, &ourkeyr);	dns_name_init(&ourname, NULL);	dns_name_clone(dst_key_name(tctx->dhkey), &ourname);	/*	 * XXXBEW The TTL should be obtained from the database, if it exists.	 */	RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, 0, namelist));	RETERR(dst_key_secretsize(tctx->dhkey, &sharedsize));	RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize));	result = dst_key_computesecret(pubkey, tctx->dhkey, shared);	if (result != ISC_R_SUCCESS) {		tkey_log("process_dhtkey: failed to compute shared secret: %s",			 isc_result_totext(result));		goto failure;	}	dst_key_free(&pubkey);	isc_buffer_init(&secret, secretdata, sizeof(secretdata));	randomdata = isc_mem_get(tctx->mctx, TKEY_RANDOM_AMOUNT);	if (randomdata == NULL)		goto failure;	result = isc_entropy_getdata(tctx->ectx, randomdata,				     TKEY_RANDOM_AMOUNT, NULL, 0);	if (result != ISC_R_SUCCESS) {		tkey_log("process_dhtkey: failed to obtain entropy: %s",			 isc_result_totext(result));		goto failure;	}	r.base = randomdata;	r.length = TKEY_RANDOM_AMOUNT;	r2.base = tkeyin->key;	r2.length = tkeyin->keylen;	RETERR(compute_secret(shared, &r2, &r, &secret));	isc_buffer_free(&shared);	RETERR(dns_tsigkey_create(name, &tkeyin->algorithm,				  isc_buffer_base(&secret),				  isc_buffer_usedlength(&secret),				  ISC_TRUE, signer, tkeyin->inception,				  tkeyin->expire, msg->mctx, ring, NULL));	/* This key is good for a long time */	tkeyout->inception = tkeyin->inception;	tkeyout->expire = tkeyin->expire;	tkeyout->key = randomdata;	tkeyout->keylen = TKEY_RANDOM_AMOUNT;	return (ISC_R_SUCCESS); failure:	if (!ISC_LIST_EMPTY(*namelist))		free_namelist(msg, namelist);	if (shared != NULL)		isc_buffer_free(&shared);	if (pubkey != NULL)		dst_key_free(&pubkey);	if (randomdata == NULL)		isc_mem_put(tctx->mctx, randomdata, TKEY_RANDOM_AMOUNT);	return (result);}static isc_result_tprocess_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,		dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx,		dns_rdata_tkey_t *tkeyout,		dns_tsig_keyring_t *ring, dns_namelist_t *namelist){	isc_result_t result = ISC_R_SUCCESS;	dst_key_t *dstkey = NULL;	void *gssctx = NULL;	isc_stdtime_t now;

⌨️ 快捷键说明

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