Commit af602636 authored by Brian Wellington's avatar Brian Wellington

Added dns_tsigkey_attach & _detach, to simplify reference counting.

Added dns_message_get/settsigkey to deuglify tsig key handling in message code.
parent 82a30bf0
212. [cleanup] Added dns_message_get/settsigkey, to make TSIG
key management reasonable.
211. [func] The 'key' and 'server' statements can now occur
inside 'view' statements.
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: xfrout.c,v 1.62 2000/05/15 21:14:01 tale Exp $ */
/* $Id: xfrout.c,v 1.63 2000/05/26 00:16:35 bwelling Exp $ */
#include <config.h>
......@@ -1028,7 +1028,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
*/
CHECK(xfrout_ctx_create(mctx, client, request->id, question_name,
reqtype, db, ver, quota, stream,
request->tsigkey, request->tsig,
dns_message_gettsigkey(request), request->tsig,
dns_zone_getmaxxfrout(zone),
dns_zone_getidleout(zone),
(format == dns_many_answers) ?
......@@ -1214,7 +1214,7 @@ sendstream(xfrout_ctx_t *xfr) {
msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
msg->flags |= DNS_MESSAGEFLAG_RA;
msg->tsigkey = xfr->tsigkey;
dns_message_settsigkey(msg, xfr->tsigkey);
msg->querytsig = xfr->lasttsig;
/*
......
......@@ -952,6 +952,29 @@ dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
* The TSIG rdataset of 'msg', or NULL if there isn't one.
*/
void
dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
/*
* Set the tsig key for 'msg'. This is only necessary for when rendering a
* query or parsing a response. The key (if non-NULL) is attached to, and
* will be detached when the message is destroyed.
*
* Requires:
*
* 'msg' is a valid message
* 'key' is a valid tsig key or NULL.
*/
dns_tsigkey_t *
dns_message_gettsigkey(dns_message_t *msg);
/*
* Gets the tsig key for 'msg'.
*
* Requires:
*
* 'msg' is a valid message
*/
dns_rdataset_t *
dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
/*
......
......@@ -102,13 +102,27 @@ dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm,
*/
void
dns_tsigkey_free(dns_tsigkey_t **key);
dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp);
/*
* Frees the tsig key structure pointed to by 'key'.
* Attach '*targetp' to 'source'.
*
* Requires:
* 'key' is a valid TSIG key
* 'ring' is a valid TSIG keyring containing the key
*
* Ensures:
* *targetp is attached to source.
*/
void
dns_tsigkey_detach(dns_tsigkey_t **key);
/*
* Detaches from the tsig key structure pointed to by '*key'.
*
* Requires:
* 'key' not NULL and '*key' is a valid TSIG key
*
* Ensures:
* 'key' points to NULL
*/
void
......
......@@ -522,7 +522,7 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) {
}
if (msg->tsigkey != NULL) {
dns_tsigkey_free(&msg->tsigkey);
dns_tsigkey_detach(&msg->tsigkey);
msg->tsigkey = NULL;
}
......@@ -2220,6 +2220,32 @@ dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
return (msg->tsigset);
}
void
dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
/*
* Set the TSIG key for 'msg'
*/
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(msg->tsigkey == NULL);
if (key != NULL)
dns_tsigkey_attach(key, &msg->tsigkey);
}
dns_tsigkey_t *
dns_message_gettsigkey(dns_message_t *msg) {
/*
* Get the TSIG key for 'msg'
*/
REQUIRE(DNS_MESSAGE_VALID(msg));
return (msg->tsigkey);
}
dns_rdataset_t *
dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
......
......@@ -537,11 +537,10 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
goto cleanup;
message->id = id;
message->tsigkey = request->tsigkey;
dns_message_settsigkey(message, request->tsigkey);
result = req_render(message, &request->query, mctx);
request->tsig = message->tsig;
message->tsig = NULL;
message->tsigkey = NULL;
if (result == DNS_R_USETCP &&
(options & DNS_REQUESTOPT_TCP) == 0) {
/*
......@@ -725,7 +724,7 @@ dns_request_getresponse(dns_request_t *request, dns_message_t *message,
message->querytsig = request->tsig;
request->tsig = NULL;
message->tsigkey = request->tsigkey;
dns_message_settsigkey(message, request->tsigkey);
return (dns_message_parse(message, request->answer, preserve_order));
}
......
......@@ -899,15 +899,20 @@ resquery_send(resquery_t *query) {
if (result == ISC_R_SUCCESS &&
dns_peer_getkey(peer, &keyname) == ISC_R_SUCCESS)
{
result = dns_tsigkey_find(&fctx->qmessage->tsigkey,
keyname, NULL,
dns_tsigkey_t *tsigkey = NULL;
result = dns_tsigkey_find(&tsigkey, keyname, NULL,
fctx->res->view->statickeys);
if (result == ISC_R_NOTFOUND)
result = dns_tsigkey_find(&fctx->qmessage->tsigkey,
keyname, NULL,
result = dns_tsigkey_find(&tsigkey, keyname, NULL,
fctx->res->view->dynamickeys);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
goto cleanup_message;
if (tsigkey != NULL) {
dns_message_settsigkey(fctx->qmessage, tsigkey);
dns_tsigkey_detach(&tsigkey);
}
}
result = dns_message_rendersection(fctx->qmessage,
......@@ -919,11 +924,11 @@ resquery_send(resquery_t *query) {
if (result != ISC_R_SUCCESS)
goto cleanup_message;
if (fctx->qmessage->tsigkey != NULL) {
query->tsigkey = fctx->qmessage->tsigkey;
if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
&query->tsigkey);
query->tsig = fctx->qmessage->tsig;
fctx->qmessage->tsig = NULL;
fctx->qmessage->tsigkey = NULL;
}
/*
......@@ -3484,7 +3489,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/* BEW - clean this up at some point */
message->querytsig = query->tsig;
message->tsigkey = query->tsigkey;
dns_message_settsigkey(message, query->tsigkey);
query->tsig = NULL;
result = dns_message_parse(message, &devent->buffer, ISC_FALSE);
......
......@@ -16,7 +16,7 @@
*/
/*
* $Id: tkey.c,v 1.39 2000/05/24 23:13:23 bwelling Exp $
* $Id: tkey.c,v 1.40 2000/05/26 00:16:40 bwelling Exp $
* Principal Author: Brian Wellington
*/
......@@ -413,7 +413,7 @@ process_deletetkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
*/
dns_tsigkey_setdeleted(tsigkey);
/* Release the reference */
dns_tsigkey_free(&tsigkey);
dns_tsigkey_detach(&tsigkey);
return (ISC_R_SUCCESS);
}
......@@ -564,7 +564,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkey_ctx_t *tctx,
result = dns_tsigkey_find(&tsigkey, keyname, NULL, ring);
if (result == ISC_R_SUCCESS) {
tkeyout.error = dns_tsigerror_badname;
dns_tsigkey_free(&tsigkey);
dns_tsigkey_detach(&tsigkey);
goto failure_with_tkey;
}
else if (result != ISC_R_NOTFOUND)
......@@ -849,6 +849,7 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
isc_buffer_t *shared = NULL, secret;
isc_region_t r, r2;
isc_result_t result;
isc_boolean_t freertkey = ISC_FALSE;
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
......@@ -860,9 +861,10 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
REQUIRE(ring != NULL);
if (rmsg->rcode != dns_rcode_noerror)
return(ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
return (ISC_RESULTCLASS_DNSRCODE + rmsg->rcode);
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, rmsg->mctx));
freertkey = ISC_TRUE;
RETERR(find_tkey(qmsg, &tempname, &qtkeyrdata,
DNS_SECTION_ADDITIONAL));
......@@ -875,10 +877,12 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
rmsg->rcode != dns_rcode_noerror)
{
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&rtkey);
dns_rdata_freestruct(&qtkey);
goto failure;
}
dns_rdata_freestruct(&qtkey);
dns_name_init(&keyname, NULL);
dns_name_clone(dst_key_name(key), &keyname);
......@@ -941,12 +945,20 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
NULL, rtkey.inception, rtkey.expire,
rmsg->mctx, ring, outkey);
isc_buffer_free(&shared);
dns_rdata_freestruct(&rtkey);
dst_key_free(&theirkey);
return (result);
failure:
if (shared != NULL)
isc_buffer_free(&shared);
if (theirkey != NULL)
dst_key_free(&theirkey);
if (freertkey)
dns_rdata_freestruct(&rtkey);
return (result);
}
......@@ -980,12 +992,17 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
rmsg->rcode != dns_rcode_noerror)
{
result = DNS_R_INVALIDTKEY;
dns_rdata_freestruct(&qtkey);
dns_rdata_freestruct(&rtkey);
goto failure;
}
dns_rdata_freestruct(&qtkey);
RETERR(dns_tsigkey_find(&tsigkey, tkeyname, &rtkey.algorithm, ring));
dns_rdata_freestruct(&rtkey);
/*
* Mark the key as deleted.
*/
......@@ -993,7 +1010,7 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
/*
* Release the reference.
*/
dns_tsigkey_free(&tsigkey);
dns_tsigkey_detach(&tsigkey);
failure:
return (result);
......
......@@ -16,7 +16,7 @@
*/
/*
* $Id: tsig.c,v 1.63 2000/05/24 23:13:25 bwelling Exp $
* $Id: tsig.c,v 1.64 2000/05/26 00:16:41 bwelling Exp $
* Principal Author: Brian Wellington
*/
......@@ -173,51 +173,58 @@ cleanup_key:
return (ret);
}
void
dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) {
REQUIRE(VALID_TSIG_KEY(source));
REQUIRE(targetp != NULL && *targetp == NULL);
isc_mutex_lock(&source->lock);
source->refs++;
isc_mutex_unlock(&source->lock);
*targetp = source;
}
static void
tsigkey_free(dns_tsigkey_t **key) {
dns_tsigkey_t *tkey;
tsigkey_free(dns_tsigkey_t *key) {
dns_tsig_keyring_t *ring;
REQUIRE(key != NULL);
REQUIRE(VALID_TSIG_KEY(*key));
tkey = *key;
*key = NULL;
ring = tkey->ring;
REQUIRE(VALID_TSIG_KEY(key));
ring = key->ring;
tkey->magic = 0;
if (tkey->key != NULL) {
key->magic = 0;
if (key->key != NULL) {
isc_rwlock_lock(&ring->lock, isc_rwlocktype_write);
ISC_LIST_UNLINK(ring->keys, tkey, link);
ISC_LIST_UNLINK(ring->keys, key, link);
isc_rwlock_unlock(&ring->lock, isc_rwlocktype_write);
}
dns_name_free(&tkey->name, tkey->mctx);
dns_name_free(&tkey->algorithm, tkey->mctx);
if (tkey->key != NULL)
dst_key_free(&tkey->key);
if (tkey->creator != NULL) {
dns_name_free(tkey->creator, tkey->mctx);
isc_mem_put(tkey->mctx, tkey->creator, sizeof(dns_name_t));
dns_name_free(&key->name, key->mctx);
dns_name_free(&key->algorithm, key->mctx);
if (key->key != NULL)
dst_key_free(&key->key);
if (key->creator != NULL) {
dns_name_free(key->creator, key->mctx);
isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t));
}
isc_mem_put(tkey->mctx, tkey, sizeof(dns_tsigkey_t));
isc_mem_put(key->mctx, key, sizeof(dns_tsigkey_t));
}
void
dns_tsigkey_free(dns_tsigkey_t **key) {
dns_tsigkey_detach(dns_tsigkey_t **key) {
dns_tsigkey_t *tkey;
REQUIRE(key != NULL);
REQUIRE(VALID_TSIG_KEY(*key));
tkey = *key;
*key = NULL;
isc_mutex_lock(&tkey->lock);
tkey->refs--;
if (tkey->refs > 0 || (!tkey->deleted && tkey->key != NULL)) {
isc_mutex_unlock(&tkey->lock);
*key = NULL;
return;
}
isc_mutex_unlock(&tkey->lock);
tsigkey_free(key);
tsigkey_free(tkey);
}
void
......@@ -247,7 +254,7 @@ dns_tsig_sign(dns_message_t *msg) {
isc_boolean_t algfreed = ISC_FALSE;
REQUIRE(msg != NULL);
REQUIRE(VALID_TSIG_KEY(msg->tsigkey));
REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg)));
REQUIRE(msg->tsig == NULL);
/*
......@@ -259,7 +266,7 @@ dns_tsig_sign(dns_message_t *msg) {
dynbuf = NULL;
mctx = msg->mctx;
key = msg->tsigkey;
key = dns_message_gettsigkey(msg);
tsig.mctx = mctx;
tsig.common.rdclass = dns_rdataclass_any;
......@@ -556,7 +563,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
dns_rdata_t rdata;
isc_stdtime_t now;
isc_result_t ret;
dns_tsigkey_t *tsigkey = NULL;
dns_tsigkey_t *tsigkey;
dst_key_t *key = NULL;
unsigned char header[DNS_MESSAGE_HEADERLEN];
dst_context_t ctx;
......@@ -566,8 +573,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
REQUIRE(source != NULL);
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(msg->tsig == NULL);
if (msg->tsigkey != NULL)
REQUIRE(VALID_TSIG_KEY(msg->tsigkey));
tsigkey = dns_message_gettsigkey(msg);
REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
msg->verify_attempted = 1;
......@@ -585,7 +592,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
* shouldn't be one on the response.
*/
if (is_response(msg) &&
(msg->tsigkey == NULL || msg->querytsig == NULL))
(tsigkey == NULL || msg->querytsig == NULL))
return (DNS_R_UNEXPECTEDTSIG);
mctx = msg->mctx;
......@@ -613,7 +620,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
* Do the key name and algorithm match that of the query?
*/
if (is_response(msg) &&
(!dns_name_equal(keyname, &msg->tsigkey->name) ||
(!dns_name_equal(keyname, &tsigkey->name) ||
!dns_name_equal(&tsig->algorithm, &msg->querytsig->algorithm)))
{
msg->tsigstatus = dns_tsigerror_badkey;
......@@ -628,7 +635,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
/*
* Find dns_tsigkey_t based on keyname.
*/
if (msg->tsigkey == NULL) {
if (tsigkey == NULL) {
ret = ISC_R_NOTFOUND;
if (sring != NULL)
ret = dns_tsigkey_find(&tsigkey, keyname,
......@@ -642,19 +649,20 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
goto cleanup_struct;
}
msg->tsigstatus = dns_tsigerror_badkey;
msg->tsigkey = NULL;
ret = dns_tsigkey_create(keyname, &tsig->algorithm,
NULL, 0, ISC_FALSE, NULL,
now, now,
mctx, dring, &msg->tsigkey);
mctx, dring, &tsigkey);
if (ret != ISC_R_SUCCESS)
goto cleanup_struct;
dns_message_settsigkey(msg, tsigkey);
dns_tsigkey_detach(&tsigkey);
return (DNS_R_TSIGVERIFYFAILURE);
}
msg->tsigkey = tsigkey;
dns_message_settsigkey(msg, tsigkey);
dns_tsigkey_detach(&tsigkey);
tsigkey = dns_message_gettsigkey(msg);
}
else
tsigkey = msg->tsigkey;
key = tsigkey->key;
......@@ -814,10 +822,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
return (ISC_R_SUCCESS);
cleanup_key:
if (dns_tsigkey_empty(msg->tsigkey)) {
dns_tsigkey_free(&msg->tsigkey);
msg->tsigkey = NULL;
}
if (dns_tsigkey_empty(tsigkey))
dns_tsigkey_detach(&tsigkey);
cleanup_struct:
dns_rdata_freestruct(tsig);
cleanup_emptystruct:
......@@ -836,6 +842,7 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
dns_rdata_t rdata;
isc_stdtime_t now;
isc_result_t ret;
dns_tsigkey_t *tsigkey;
dst_key_t *key = NULL;
unsigned char header[DNS_MESSAGE_HEADERLEN];
isc_mem_t *mctx;
......@@ -845,13 +852,15 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
REQUIRE(source != NULL);
REQUIRE(msg != NULL);
REQUIRE(msg->tsig == NULL);
REQUIRE(msg->tsigkey != NULL);
REQUIRE(dns_message_gettsigkey(msg) != NULL);
REQUIRE(msg->tcp_continuation == 1);
REQUIRE(is_response(msg));
REQUIRE(msg->querytsig != NULL);
mctx = msg->mctx;
tsigkey = dns_message_gettsigkey(msg);
if (msg->tsigset != NULL) {
has_tsig = ISC_TRUE;
......@@ -872,7 +881,7 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
/*
* Do the key name and algorithm match that of the query?
*/
if (!dns_name_equal(keyname, &msg->tsigkey->name) ||
if (!dns_name_equal(keyname, &tsigkey->name) ||
!dns_name_equal(&tsig->algorithm,
&msg->querytsig->algorithm))
{
......@@ -890,7 +899,7 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
}
}
key = msg->tsigkey->key;
key = tsigkey->key;
if (msg->tsigctx == NULL) {
ret = dst_key_verify(DST_SIGMODE_INIT, key, &msg->tsigctx,
......@@ -1105,7 +1114,7 @@ dns_tsigkeyring_destroy(dns_tsig_keyring_t **ring) {
dns_tsigkey_t *key = ISC_LIST_HEAD((*ring)->keys);
key->refs = 0;
key->deleted = ISC_TRUE;
tsigkey_free(&key);
tsigkey_free(key);
}
isc_rwlock_destroy(&(*ring)->lock);
mctx = (*ring)->mctx;
......
......@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: xfrin.c,v 1.71 2000/05/18 16:47:14 gson Exp $ */
/* $Id: xfrin.c,v 1.72 2000/05/26 00:16:43 bwelling Exp $ */
#include <config.h>
......@@ -816,7 +816,7 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) {
/* Create the request message */
CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
msg->tsigkey = xfr->tsigkey;
dns_message_settsigkey(msg, xfr->tsigkey);
/* Create a name for the question section. */
dns_message_gettempname(msg, &qname);
......@@ -970,7 +970,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
msg->tsigkey = xfr->tsigkey;
dns_message_settsigkey(msg, xfr->tsigkey);
msg->querytsig = xfr->lasttsig;
msg->tsigctx = xfr->tsigctx;
if (xfr->nmsg > 0)
......@@ -1054,7 +1054,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
* Reset msg->tsig so it doesn't get freed.
*/
msg->tsig = NULL;
} else if (msg->tsigkey != NULL) {
} else if (dns_message_gettsigkey(msg) != NULL) {
xfr->sincetsig++;
if (xfr->sincetsig > 100 ||
xfr->nmsg == 0 || xfr->state == XFRST_END)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment