mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
The message code now has functions to manipulate TSIG and SIG(0), and the
callers use these functions. Also a lot of TSIG cleanup.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrout.c,v 1.63 2000/05/26 00:16:35 bwelling Exp $ */
|
||||
/* $Id: xfrout.c,v 1.64 2000/05/30 23:14:48 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <dns/db.h>
|
||||
#include <dns/dbiterator.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/message.h>
|
||||
#include <dns/peer.h>
|
||||
@@ -741,7 +742,7 @@ typedef struct {
|
||||
unsigned int txmemlen;
|
||||
unsigned int nmsg; /* Number of messages sent */
|
||||
dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
|
||||
dns_rdata_any_tsig_t *lasttsig; /* the last TSIG */
|
||||
isc_buffer_t *lasttsig; /* the last TSIG */
|
||||
isc_boolean_t many_answers;
|
||||
int sends; /* Send in progress */
|
||||
isc_boolean_t shuttingdown;
|
||||
@@ -752,7 +753,7 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client,
|
||||
unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype,
|
||||
dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
|
||||
rrstream_t *stream, dns_tsigkey_t *tsigkey,
|
||||
dns_rdata_any_tsig_t *lasttsig,
|
||||
isc_buffer_t *lasttsig,
|
||||
unsigned int maxtime,
|
||||
unsigned int idletime,
|
||||
isc_boolean_t many_answers,
|
||||
@@ -810,6 +811,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
|
||||
dns_transfer_format_t format = client->view->transfer_format;
|
||||
isc_netaddr_t na;
|
||||
dns_peer_t *peer = NULL;
|
||||
isc_buffer_t *tsigbuf = NULL;
|
||||
|
||||
switch (reqtype) {
|
||||
case dns_rdatatype_axfr:
|
||||
@@ -1022,13 +1024,15 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
|
||||
data_stream = NULL;
|
||||
|
||||
have_stream:
|
||||
CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf));
|
||||
/*
|
||||
* Create the xfrout context object. This transfers the ownership
|
||||
* of "stream", "db", "ver", and "quota" to the xfrout context object.
|
||||
*/
|
||||
CHECK(xfrout_ctx_create(mctx, client, request->id, question_name,
|
||||
reqtype, db, ver, quota, stream,
|
||||
dns_message_gettsigkey(request), request->tsig,
|
||||
dns_message_gettsigkey(request),
|
||||
tsigbuf,
|
||||
dns_zone_getmaxxfrout(zone),
|
||||
dns_zone_getidleout(zone),
|
||||
(format == dns_many_answers) ?
|
||||
@@ -1084,7 +1088,7 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
||||
dns_name_t *qname, dns_rdatatype_t qtype,
|
||||
dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
|
||||
rrstream_t *stream, dns_tsigkey_t *tsigkey,
|
||||
dns_rdata_any_tsig_t *lasttsig, unsigned int maxtime,
|
||||
isc_buffer_t *lasttsig, unsigned int maxtime,
|
||||
unsigned int idletime, isc_boolean_t many_answers,
|
||||
xfrout_ctx_t **xfrp)
|
||||
{
|
||||
@@ -1215,7 +1219,9 @@ sendstream(xfrout_ctx_t *xfr) {
|
||||
if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
|
||||
msg->flags |= DNS_MESSAGEFLAG_RA;
|
||||
dns_message_settsigkey(msg, xfr->tsigkey);
|
||||
msg->querytsig = xfr->lasttsig;
|
||||
CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
|
||||
if (xfr->lasttsig != NULL)
|
||||
isc_buffer_free(&xfr->lasttsig);
|
||||
|
||||
/*
|
||||
* Include a question section in the first message only.
|
||||
@@ -1384,17 +1390,7 @@ sendstream(xfrout_ctx_t *xfr) {
|
||||
}
|
||||
|
||||
/* Advance lasttsig to be the last TSIG generated */
|
||||
xfr->lasttsig = msg->tsig;
|
||||
|
||||
/* Clear this field so the TSIG is not destroyed */
|
||||
msg->tsig = NULL;
|
||||
|
||||
/*
|
||||
* If this is the first message, clear this too, since this is
|
||||
* also pointed to by the request.
|
||||
*/
|
||||
if (xfr->nmsg == 0)
|
||||
msg->querytsig = NULL;
|
||||
CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
|
||||
|
||||
xfr->nmsg++;
|
||||
|
||||
@@ -1426,10 +1422,8 @@ xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
|
||||
isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length);
|
||||
if (xfr->txmem != NULL)
|
||||
isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen);
|
||||
if (xfr->lasttsig != NULL) {
|
||||
dns_rdata_freestruct(xfr->lasttsig);
|
||||
isc_mem_put(xfr->mctx, xfr->lasttsig, sizeof(*xfr->lasttsig));
|
||||
}
|
||||
if (xfr->lasttsig != NULL)
|
||||
isc_buffer_free(&xfr->lasttsig);
|
||||
if (xfr->quota != NULL)
|
||||
isc_quota_detach(&xfr->quota);
|
||||
if (xfr->ver != NULL)
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include <isc/magic.h>
|
||||
|
||||
#include <dns/compress.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
@@ -178,6 +177,7 @@ struct dns_message {
|
||||
unsigned int verify_attempted : 1;
|
||||
|
||||
unsigned int opt_reserved;
|
||||
unsigned int sig_reserved;
|
||||
unsigned int reserved; /* reserved space (render) */
|
||||
|
||||
isc_buffer_t *buffer;
|
||||
@@ -199,8 +199,7 @@ struct dns_message {
|
||||
dns_rcode_t tsigstatus;
|
||||
dns_rcode_t querytsigstatus;
|
||||
dns_name_t *tsigname;
|
||||
dns_rdata_any_tsig_t *tsig;
|
||||
dns_rdata_any_tsig_t *querytsig;
|
||||
dns_rdataset_t *querytsigset;
|
||||
dns_tsigkey_t *tsigkey;
|
||||
void *tsigctx;
|
||||
int sigstart;
|
||||
@@ -952,7 +951,7 @@ dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
|
||||
* The TSIG rdataset of 'msg', or NULL if there isn't one.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
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
|
||||
@@ -961,8 +960,16 @@ dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' is a valid message
|
||||
* 'msg' is a valid message with rendering intent,
|
||||
* dns_message_renderbegin() has been called, and no sections have been
|
||||
* rendered.
|
||||
* 'key' is a valid tsig key or NULL.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS -- all is well.
|
||||
*
|
||||
* ISC_R_NOSPACE -- there is no space for the TSIG record.
|
||||
*/
|
||||
|
||||
dns_tsigkey_t *
|
||||
@@ -975,6 +982,50 @@ dns_message_gettsigkey(dns_message_t *msg);
|
||||
* 'msg' is a valid message
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
|
||||
/*
|
||||
* Indicates that 'querytsig' is the TSIG from the signed query for which
|
||||
* 'msg' is the response. This is also used for chained TSIGs in TCP
|
||||
* responses.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
|
||||
* or NULL
|
||||
*
|
||||
* 'msg' is a valid message
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_NOMEMORY
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
|
||||
isc_buffer_t **querytsig);
|
||||
/*
|
||||
* Gets the tsig from the TSIG from the signed query 'msg'. This is also used
|
||||
* for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes
|
||||
* a copy of the data, so can be used if the message is destroyed.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' is a valid signed message
|
||||
* 'mctx' is a valid memory context
|
||||
* querytsig != NULL && *querytsig == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_NOMEMORY
|
||||
*
|
||||
* Ensures:
|
||||
* 'tsig' points to NULL or an allocated buffer which must be freed
|
||||
* by the caller.
|
||||
*/
|
||||
|
||||
dns_rdataset_t *
|
||||
dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
|
||||
/*
|
||||
@@ -990,6 +1041,35 @@ dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
|
||||
* The SIG(0) rdataset of 'msg', or NULL if there isn't one.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
|
||||
/*
|
||||
* Set the SIG(0) key for 'msg'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' is a valid message with rendering intent,
|
||||
* dns_message_renderbegin() has been called, and no sections have been
|
||||
* rendered.
|
||||
* 'key' is a valid sig key or NULL.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ISC_R_SUCCESS -- all is well.
|
||||
*
|
||||
* ISC_R_NOSPACE -- there is no space for the SIG(0) record.
|
||||
*/
|
||||
|
||||
dst_key_t *
|
||||
dns_message_getsig0key(dns_message_t *msg);
|
||||
/*
|
||||
* Gets the SIG(0) key for 'msg'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' is a valid message
|
||||
*/
|
||||
|
||||
void
|
||||
dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
|
||||
/*
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/tsig.h>
|
||||
#include <dns/view.h>
|
||||
@@ -325,6 +326,7 @@ msginitprivate(dns_message_t *m) {
|
||||
m->tsigname = NULL;
|
||||
m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
|
||||
m->opt_reserved = 0;
|
||||
m->sig_reserved = 0;
|
||||
m->reserved = 0;
|
||||
m->buffer = NULL;
|
||||
m->need_cctx_cleanup = 0;
|
||||
@@ -332,8 +334,8 @@ msginitprivate(dns_message_t *m) {
|
||||
|
||||
static inline void
|
||||
msginittsig(dns_message_t *m) {
|
||||
m->tsigstatus = m->querytsigstatus = dns_rcode_noerror;
|
||||
m->tsig = m->querytsig = NULL;
|
||||
m->tsigstatus = dns_rcode_noerror;
|
||||
m->querytsigstatus = dns_rcode_noerror;
|
||||
m->tsigkey = NULL;
|
||||
m->tsigctx = NULL;
|
||||
m->sigstart = -1;
|
||||
@@ -341,6 +343,7 @@ msginittsig(dns_message_t *m) {
|
||||
m->sig0status = dns_rcode_noerror;
|
||||
m->query = NULL;
|
||||
m->saved = NULL;
|
||||
m->querytsigset = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -406,12 +409,26 @@ msgresetopt(dns_message_t *msg)
|
||||
}
|
||||
|
||||
static void
|
||||
msgresetsigs(dns_message_t *msg) {
|
||||
msgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
|
||||
if (msg->sig_reserved > 0) {
|
||||
dns_message_renderrelease(msg, msg->sig_reserved);
|
||||
msg->sig_reserved = 0;
|
||||
}
|
||||
if (msg->tsigset != NULL) {
|
||||
INSIST(dns_rdataset_isassociated(msg->tsigset));
|
||||
INSIST(msg->namepool != NULL);
|
||||
dns_rdataset_disassociate(msg->tsigset);
|
||||
isc_mempool_put(msg->rdspool, msg->tsigset);
|
||||
if (replying) {
|
||||
INSIST(msg->querytsigset == NULL);
|
||||
msg->querytsigset = msg->tsigset;
|
||||
} else {
|
||||
dns_rdataset_disassociate(msg->tsigset);
|
||||
isc_mempool_put(msg->rdspool, msg->tsigset);
|
||||
if (msg->querytsigset != NULL) {
|
||||
dns_rdataset_disassociate(msg->querytsigset);
|
||||
isc_mempool_put(msg->rdspool,
|
||||
msg->querytsigset);
|
||||
}
|
||||
}
|
||||
isc_mempool_put(msg->namepool, msg->tsigname);
|
||||
msg->tsigset = NULL;
|
||||
msg->tsigname = NULL;
|
||||
@@ -440,7 +457,7 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) {
|
||||
|
||||
msgresetnames(msg, 0);
|
||||
msgresetopt(msg);
|
||||
msgresetsigs(msg);
|
||||
msgresetsigs(msg, ISC_FALSE);
|
||||
|
||||
/*
|
||||
* Clean up linked lists.
|
||||
@@ -507,20 +524,6 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) {
|
||||
if (msg->need_cctx_cleanup == 1)
|
||||
dns_compress_invalidate(&msg->cctx);
|
||||
|
||||
if (msg->tsig != NULL) {
|
||||
dns_rdata_freestruct(msg->tsig);
|
||||
isc_mem_put(msg->mctx, msg->tsig,
|
||||
sizeof(dns_rdata_any_tsig_t));
|
||||
msg->tsig = NULL;
|
||||
}
|
||||
|
||||
if (msg->querytsig != NULL) {
|
||||
dns_rdata_freestruct(msg->querytsig);
|
||||
isc_mem_put(msg->mctx, msg->querytsig,
|
||||
sizeof(dns_rdata_any_tsig_t));
|
||||
msg->querytsig = NULL;
|
||||
}
|
||||
|
||||
if (msg->tsigkey != NULL) {
|
||||
dns_tsigkey_detach(&msg->tsigkey);
|
||||
msg->tsigkey = NULL;
|
||||
@@ -556,6 +559,43 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) {
|
||||
msginit(msg);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
spacefortsig(dns_tsigkey_t *key, int otherlen) {
|
||||
isc_region_t r1, r2;
|
||||
unsigned int x;
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* The space required for an TSIG record is:
|
||||
*
|
||||
* n1 bytes for the name
|
||||
* 2 bytes for the type
|
||||
* 2 bytes for the class
|
||||
* 4 bytes for the ttl
|
||||
* 6 bytes for the time signed
|
||||
* 2 bytes for the fudge
|
||||
* 2 bytes for the MAC size
|
||||
* x bytes for the MAC
|
||||
* 2 bytes for the original id
|
||||
* 2 bytes for the error
|
||||
* 2 bytes for the other data length
|
||||
* y bytes for the other data (at most)
|
||||
* ---------------------------------
|
||||
* 30 + n1 + n2 + x + y bytes
|
||||
*/
|
||||
|
||||
dns_name_toregion(&key->name, &r1);
|
||||
dns_name_toregion(&key->algorithm, &r2);
|
||||
if (key->key == NULL)
|
||||
x = 0;
|
||||
else {
|
||||
result = dst_key_sigsize(key->key, &x);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
x = 0;
|
||||
}
|
||||
return (24 + r1.length + r2.length + x + otherlen);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
|
||||
{
|
||||
@@ -1486,6 +1526,9 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer) {
|
||||
isc_buffer_availableregion(buffer, &r);
|
||||
REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
|
||||
|
||||
if (r.length < msg->reserved)
|
||||
return (ISC_R_NOSPACE);
|
||||
|
||||
result = dns_compress_init(&msg->cctx, -1, msg->mctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
@@ -1533,7 +1576,6 @@ dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
|
||||
void
|
||||
dns_message_renderrelease(dns_message_t *msg, unsigned int space) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->buffer != NULL);
|
||||
REQUIRE(space <= msg->reserved);
|
||||
|
||||
msg->reserved -= space;
|
||||
@@ -1544,11 +1586,12 @@ dns_message_renderreserve(dns_message_t *msg, unsigned int space) {
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->buffer != NULL);
|
||||
|
||||
isc_buffer_availableregion(msg->buffer, &r);
|
||||
if (r.length < (space + msg->reserved))
|
||||
return (ISC_R_NOSPACE);
|
||||
if (msg->buffer != NULL) {
|
||||
isc_buffer_availableregion(msg->buffer, &r);
|
||||
if (r.length < (space + msg->reserved))
|
||||
return (ISC_R_NOSPACE);
|
||||
}
|
||||
|
||||
msg->reserved += space;
|
||||
|
||||
@@ -1772,7 +1815,8 @@ dns_message_renderend(dns_message_t *msg) {
|
||||
}
|
||||
|
||||
if (msg->tsigkey != NULL) {
|
||||
REQUIRE(msg->tsig == NULL);
|
||||
dns_message_renderrelease(msg, msg->sig_reserved);
|
||||
msg->sig_reserved = 0;
|
||||
result = dns_tsig_sign(msg);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
@@ -1785,6 +1829,8 @@ dns_message_renderend(dns_message_t *msg) {
|
||||
}
|
||||
|
||||
else if (msg->sig0key != NULL) {
|
||||
dns_message_renderrelease(msg, msg->sig_reserved);
|
||||
msg->sig_reserved = 0;
|
||||
result = dns_dnssec_signmessage(msg, msg->sig0key);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
@@ -2100,6 +2146,7 @@ dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
|
||||
isc_result_t
|
||||
dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
|
||||
unsigned int first_section;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
|
||||
@@ -2118,7 +2165,7 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
|
||||
msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
|
||||
msgresetnames(msg, first_section);
|
||||
msgresetopt(msg);
|
||||
msgresetsigs(msg);
|
||||
msgresetsigs(msg, ISC_TRUE);
|
||||
msginitprivate(msg);
|
||||
/*
|
||||
* We now clear most flags and then set QR, ensuring that the
|
||||
@@ -2128,15 +2175,21 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
|
||||
msg->flags |= DNS_MESSAGEFLAG_QR;
|
||||
|
||||
/*
|
||||
* This saves the query TSIG information for later use, if there is
|
||||
* any. This only happens once - that is, if dns_message_reply
|
||||
* has already moved the variables, this has no effect.
|
||||
* This saves the query TSIG status, if the query was signed, and
|
||||
* reserves space in the reply for the TSIG.
|
||||
*/
|
||||
if (msg->tsig != NULL) {
|
||||
msg->querytsig = msg->tsig;
|
||||
msg->tsig = NULL;
|
||||
if (msg->querytsigset != NULL) {
|
||||
unsigned int otherlen = 0;
|
||||
msg->querytsigstatus = msg->tsigstatus;
|
||||
msg->tsigstatus = dns_rcode_noerror;
|
||||
if (msg->querytsigstatus == dns_tsigerror_badtime)
|
||||
otherlen = 6;
|
||||
msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen);
|
||||
result = dns_message_renderreserve(msg, msg->sig_reserved);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
msg->sig_reserved = 0;
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
if (msg->saved != NULL) {
|
||||
msg->query = msg->saved;
|
||||
@@ -2188,7 +2241,6 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
|
||||
REQUIRE(msg->state == DNS_SECTION_ANY);
|
||||
|
||||
msgresetopt(msg);
|
||||
msgresetsigs(msg);
|
||||
|
||||
result = dns_rdataset_first(opt);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -2220,18 +2272,31 @@ dns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
|
||||
return (msg->tsigset);
|
||||
}
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* Set the TSIG key for 'msg'
|
||||
*/
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->tsigkey == NULL);
|
||||
REQUIRE(msg->state == DNS_SECTION_ANY);
|
||||
REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
|
||||
|
||||
if (key != NULL)
|
||||
if (key != NULL) {
|
||||
dns_tsigkey_attach(key, &msg->tsigkey);
|
||||
if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
|
||||
msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
|
||||
result = dns_message_renderreserve(msg,
|
||||
msg->sig_reserved);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
msg->sig_reserved = 0;
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_tsigkey_t *
|
||||
@@ -2246,6 +2311,88 @@ dns_message_gettsigkey(dns_message_t *msg) {
|
||||
return (msg->tsigkey);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
|
||||
dns_rdata_t *rdata = NULL;
|
||||
dns_rdatalist_t *list = NULL;
|
||||
dns_rdataset_t *set = NULL;
|
||||
isc_buffer_t *buf = NULL;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->querytsigset == NULL);
|
||||
|
||||
if (querytsig == NULL)
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
result = dns_message_gettemprdata(msg, &rdata);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_message_gettemprdatalist(msg, &list);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_message_gettemprdataset(msg, &set);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
isc_buffer_usedregion(querytsig, &r);
|
||||
result = isc_buffer_allocate(msg->mctx, &buf, r.length);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
isc_buffer_putmem(buf, r.base, r.length);
|
||||
isc_buffer_usedregion(buf, &r);
|
||||
dns_rdata_init(rdata);
|
||||
dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
|
||||
dns_message_takebuffer(msg, &buf);
|
||||
ISC_LIST_INIT(list->rdata);
|
||||
ISC_LIST_APPEND(list->rdata, rdata, link);
|
||||
result = dns_rdatalist_tordataset(list, set);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
msg->querytsigset = set;
|
||||
|
||||
return (result);
|
||||
|
||||
cleanup:
|
||||
if (rdata != NULL)
|
||||
dns_message_puttemprdata(msg, &rdata);
|
||||
if (list != NULL)
|
||||
dns_message_puttemprdatalist(msg, &list);
|
||||
if (set != NULL)
|
||||
dns_message_puttemprdataset(msg, &set);
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
|
||||
isc_buffer_t **querytsig) {
|
||||
isc_result_t result;
|
||||
dns_rdata_t rdata;
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(querytsig != NULL && *querytsig == NULL);
|
||||
|
||||
if (msg->tsigset == NULL)
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
result = dns_rdataset_first(msg->tsigset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
dns_rdataset_current(msg->tsigset, &rdata);
|
||||
dns_rdata_toregion(&rdata, &r);
|
||||
|
||||
result = isc_buffer_allocate(mctx, querytsig, r.length);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
isc_buffer_putmem(*querytsig, r.base, r.length);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_rdataset_t *
|
||||
dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
|
||||
|
||||
@@ -2272,6 +2419,71 @@ dns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
|
||||
isc_region_t r;
|
||||
unsigned int x;
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* Set the SIG(0) key for 'msg'
|
||||
*/
|
||||
|
||||
/*
|
||||
* The space required for an SIG(0) record is:
|
||||
*
|
||||
* 1 byte for the name
|
||||
* 2 bytes for the type
|
||||
* 2 bytes for the class
|
||||
* 4 bytes for the ttl
|
||||
* 2 bytes for the type covered
|
||||
* 1 byte for the algorithm
|
||||
* 1 bytes for the labels
|
||||
* 4 bytes for the original ttl
|
||||
* 4 bytes for the signature expiration
|
||||
* 4 bytes for the signature inception
|
||||
* 2 bytes for the key tag
|
||||
* n bytes for the signer's name
|
||||
* x bytes for the signature
|
||||
* ---------------------------------
|
||||
* 27 + n + x bytes
|
||||
*/
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
|
||||
REQUIRE(msg->buffer != NULL);
|
||||
REQUIRE(msg->state == DNS_SECTION_ANY);
|
||||
REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
|
||||
|
||||
msg->sig0key = key;
|
||||
if (key != NULL) {
|
||||
dns_name_toregion(dst_key_name(key), &r);
|
||||
result = dst_key_sigsize(key, &x);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
msg->sig_reserved = 0;
|
||||
return (result);
|
||||
}
|
||||
msg->sig_reserved = 27 + r.length + x;
|
||||
result = dns_message_renderreserve(msg, msg->sig_reserved);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
msg->sig_reserved = 0;
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dst_key_t *
|
||||
dns_message_getsig0key(dns_message_t *msg) {
|
||||
|
||||
/*
|
||||
* Get the SIG(0) key for 'msg'
|
||||
*/
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
|
||||
return (msg->sig0key);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
@@ -2286,12 +2498,13 @@ isc_result_t
|
||||
dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
|
||||
isc_region_t r;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_rdata_t rdata;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(signer != NULL);
|
||||
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
|
||||
|
||||
if ((msg->tsig == NULL || msg->tsigkey == NULL) && msg->sig0 == NULL)
|
||||
if (msg->tsigset == NULL && msg->sig0 == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
if (msg->verify_attempted == 0)
|
||||
@@ -2307,14 +2520,13 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
|
||||
}
|
||||
|
||||
if (msg->sig0 != NULL) {
|
||||
dns_rdata_t rdata;
|
||||
dns_rdata_sig_t sig;
|
||||
|
||||
result = dns_rdataset_first(msg->sig0);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_rdataset_current(msg->sig0, &rdata);
|
||||
|
||||
result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
|
||||
result = dns_rdata_tostruct(&rdata, &sig, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
@@ -2328,9 +2540,16 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
|
||||
}
|
||||
else {
|
||||
dns_name_t *identity;
|
||||
dns_rdata_any_tsig_t tsig;
|
||||
|
||||
result = dns_rdataset_first(msg->tsigset);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_rdataset_current(msg->tsigset, &rdata);
|
||||
|
||||
result = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
||||
if (msg->tsigstatus != dns_rcode_noerror)
|
||||
result = DNS_R_TSIGVERIFYFAILURE;
|
||||
else if (msg->tsig->error != dns_rcode_noerror)
|
||||
else if (tsig.error != dns_rcode_noerror)
|
||||
result = DNS_R_TSIGERRORSET;
|
||||
else
|
||||
result = ISC_R_SUCCESS;
|
||||
@@ -2342,6 +2561,7 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) {
|
||||
}
|
||||
dns_name_toregion(identity, &r);
|
||||
dns_name_fromregion(signer, &r);
|
||||
dns_rdata_freestruct(&tsig);
|
||||
}
|
||||
|
||||
return (result);
|
||||
|
@@ -78,7 +78,7 @@ struct dns_request {
|
||||
dns_dispentry_t *dispentry;
|
||||
isc_timer_t *timer;
|
||||
dns_requestmgr_t *requestmgr;
|
||||
dns_rdata_any_tsig_t *tsig;
|
||||
isc_buffer_t *tsig;
|
||||
dns_tsigkey_t *tsigkey;
|
||||
|
||||
};
|
||||
@@ -539,8 +539,6 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
message->id = id;
|
||||
dns_message_settsigkey(message, request->tsigkey);
|
||||
result = req_render(message, &request->query, mctx);
|
||||
request->tsig = message->tsig;
|
||||
message->tsig = NULL;
|
||||
if (result == DNS_R_USETCP &&
|
||||
(options & DNS_REQUESTOPT_TCP) == 0) {
|
||||
/*
|
||||
@@ -557,6 +555,10 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message,
|
||||
if (result != ISC_R_SUCCESS && result != DNS_R_USETCP)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_message_getquerytsig(message, mctx, &request->tsig);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
isc_mem_attach(mctx, &request->mctx);
|
||||
LOCK(&requestmgr->lock);
|
||||
if (requestmgr->exiting) {
|
||||
@@ -722,8 +724,7 @@ dns_request_getresponse(dns_request_t *request, dns_message_t *message,
|
||||
req_log(ISC_LOG_DEBUG(3), "dns_request_getresponse: request %p",
|
||||
request);
|
||||
|
||||
message->querytsig = request->tsig;
|
||||
request->tsig = NULL;
|
||||
dns_message_setquerytsig(message, request->tsig);
|
||||
dns_message_settsigkey(message, request->tsigkey);
|
||||
return (dns_message_parse(message, request->answer, preserve_order));
|
||||
}
|
||||
@@ -900,11 +901,8 @@ req_destroy(dns_request_t *request) {
|
||||
dns_dispatch_detach(&request->dispatch);
|
||||
if (request->timer != NULL)
|
||||
isc_timer_detach(&request->timer);
|
||||
if (request->tsig != NULL) {
|
||||
dns_rdata_freestruct(request->tsig);
|
||||
isc_mem_put(request->mctx, request->tsig,
|
||||
sizeof(*request->tsig));
|
||||
}
|
||||
if (request->tsig != NULL)
|
||||
isc_buffer_free(&request->tsig);
|
||||
requestmgr_detach(&request->requestmgr);
|
||||
mctx = request->mctx;
|
||||
isc_mem_put(mctx, request, sizeof(*request));
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/resolver.h>
|
||||
#include <dns/result.h>
|
||||
@@ -103,7 +104,7 @@ typedef struct query {
|
||||
dns_dispentry_t * dispentry;
|
||||
ISC_LINK(struct query) link;
|
||||
isc_buffer_t buffer;
|
||||
dns_rdata_any_tsig_t *tsig;
|
||||
isc_buffer_t *tsig;
|
||||
dns_tsigkey_t *tsigkey;
|
||||
unsigned int options;
|
||||
unsigned int attributes;
|
||||
@@ -384,11 +385,8 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
|
||||
if (query->dispentry != NULL)
|
||||
dns_dispatch_removeresponse(&query->dispentry, deventp);
|
||||
ISC_LIST_UNLINK(fctx->queries, query, link);
|
||||
if (query->tsig != NULL) {
|
||||
dns_rdata_freestruct(query->tsig);
|
||||
isc_mem_put(query->fctx->res->mctx, query->tsig,
|
||||
sizeof(*query->tsig));
|
||||
}
|
||||
if (query->tsig != NULL)
|
||||
isc_buffer_free(&query->tsig);
|
||||
if (RESQUERY_CONNECTING(query)) {
|
||||
/*
|
||||
* Cancel the connect.
|
||||
@@ -933,8 +931,11 @@ resquery_send(resquery_t *query) {
|
||||
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;
|
||||
result = dns_message_getquerytsig(fctx->qmessage,
|
||||
fctx->res->mctx,
|
||||
&query->tsig);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_message;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3473,6 +3474,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
isc_time_t tnow, *finish;
|
||||
dns_adbaddrinfo_t *addrinfo;
|
||||
unsigned int options;
|
||||
dns_name_t *tsigowner = NULL;
|
||||
|
||||
REQUIRE(VALID_QUERY(query));
|
||||
fctx = query->fctx;
|
||||
@@ -3534,10 +3536,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
message = fctx->rmessage;
|
||||
|
||||
/* BEW - clean this up at some point */
|
||||
message->querytsig = query->tsig;
|
||||
dns_message_settsigkey(message, query->tsigkey);
|
||||
query->tsig = NULL;
|
||||
if (query->tsig != NULL) {
|
||||
result = dns_message_setquerytsig(message, query->tsig);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = dns_message_parse(message, &devent->buffer, ISC_FALSE);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@@ -3623,10 +3626,21 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
result = dns_message_checksig(message, fctx->res->view);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
if (message->tsig != NULL && message->tsig->error != dns_rcode_noerror)
|
||||
{
|
||||
result = DNS_R_FORMERR; /* BEW - good enough for now */
|
||||
goto done;
|
||||
if (dns_message_gettsig(message, &tsigowner) != NULL) {
|
||||
dns_rdata_any_tsig_t tsig;
|
||||
dns_rdata_t rdata;
|
||||
|
||||
result = dns_rdataset_first(message->tsigset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
dns_rdataset_current(message->tsigset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
if (tsig.error != dns_rcode_noerror) {
|
||||
result = DNS_R_FORMERR; /* BEW - good enough for now */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
238
lib/dns/tsig.c
238
lib/dns/tsig.c
@@ -16,13 +16,14 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: tsig.c,v 1.65 2000/05/27 00:24:07 bwelling Exp $
|
||||
* $Id: tsig.c,v 1.66 2000/05/30 23:14:54 bwelling Exp $
|
||||
* Principal Author: Brian Wellington
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h> /* Required for abs(). */
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/string.h> /* Required for HP/UX (and others?) */
|
||||
@@ -33,6 +34,7 @@
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/tsig.h>
|
||||
|
||||
@@ -238,7 +240,7 @@ dns_tsigkey_setdeleted(dns_tsigkey_t *key) {
|
||||
isc_result_t
|
||||
dns_tsig_sign(dns_message_t *msg) {
|
||||
dns_tsigkey_t *key;
|
||||
dns_rdata_any_tsig_t tsig;
|
||||
dns_rdata_any_tsig_t tsig, querytsig;
|
||||
unsigned char data[128];
|
||||
isc_buffer_t databuf, sigbuf;
|
||||
isc_buffer_t *dynbuf;
|
||||
@@ -251,16 +253,14 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
dst_context_t ctx;
|
||||
isc_mem_t *mctx;
|
||||
isc_result_t ret;
|
||||
isc_boolean_t algfreed = ISC_FALSE;
|
||||
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg)));
|
||||
REQUIRE(msg->tsig == NULL);
|
||||
|
||||
/*
|
||||
* If this is a response, there should be a query tsig.
|
||||
*/
|
||||
if (is_response(msg) && msg->querytsig == NULL)
|
||||
if (is_response(msg) && msg->querytsigset == NULL)
|
||||
return (DNS_R_EXPECTEDTSIG);
|
||||
|
||||
dynbuf = NULL;
|
||||
@@ -273,9 +273,7 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
tsig.common.rdtype = dns_rdatatype_tsig;
|
||||
ISC_LINK_INIT(&tsig.common, link);
|
||||
dns_name_init(&tsig.algorithm, NULL);
|
||||
ret = dns_name_dup(&key->algorithm, mctx, &tsig.algorithm);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
dns_name_clone(&key->algorithm, &tsig.algorithm);
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
tsig.timesigned = now;
|
||||
@@ -318,24 +316,37 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
ret = dst_key_sign(DST_SIGMODE_INIT, key->key, &ctx, NULL,
|
||||
NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_algorithm;
|
||||
goto cleanup_other;
|
||||
|
||||
/*
|
||||
* If this is a response, digest the query signature.
|
||||
*/
|
||||
if (is_response(msg)) {
|
||||
isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
|
||||
isc_buffer_availableregion(&databuf, &r);
|
||||
if (r.length < msg->querytsig->siglen)
|
||||
return (ISC_R_NOSPACE);
|
||||
memcpy(r.base, msg->querytsig->signature,
|
||||
msg->querytsig->siglen);
|
||||
isc_buffer_add(&databuf, msg->querytsig->siglen);
|
||||
dns_rdata_t querytsigrdata;
|
||||
|
||||
ret = dns_rdataset_first(msg->querytsigset);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_other;
|
||||
dns_rdataset_current(msg->querytsigset,
|
||||
&querytsigrdata);
|
||||
ret = dns_rdata_tostruct(&querytsigrdata, &querytsig,
|
||||
NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_other;
|
||||
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
||||
if (isc_buffer_availablelength(&databuf) <
|
||||
querytsig.siglen)
|
||||
{
|
||||
ret = ISC_R_NOSPACE;
|
||||
goto cleanup_other;
|
||||
}
|
||||
isc_buffer_putmem(&databuf, querytsig.signature,
|
||||
querytsig.siglen);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_sign(DST_SIGMODE_UPDATE, key->key, &ctx,
|
||||
&r, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_algorithm;
|
||||
goto cleanup_other;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -396,7 +407,7 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
0xFFFFFFFF));
|
||||
}
|
||||
else {
|
||||
isc_uint64_t querysigned = msg->querytsig->timesigned;
|
||||
isc_uint64_t querysigned = querytsig.timesigned;
|
||||
isc_buffer_putuint16(&databuf,
|
||||
(isc_uint16_t)(querysigned >>
|
||||
32));
|
||||
@@ -472,6 +483,8 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_dynbuf;
|
||||
|
||||
dns_message_takebuffer(msg, &dynbuf);
|
||||
|
||||
if (tsig.signature != NULL) {
|
||||
isc_mem_put(mctx, tsig.signature, tsig.siglen);
|
||||
tsig.signature = NULL;
|
||||
@@ -480,29 +493,16 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
isc_mem_put(mctx, tsig.other, tsig.otherlen);
|
||||
tsig.other = NULL;
|
||||
}
|
||||
dns_name_free(&tsig.algorithm, mctx);
|
||||
algfreed = ISC_TRUE;
|
||||
|
||||
msg->tsig = isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
|
||||
if (msg->tsig == NULL) {
|
||||
ret = ISC_R_NOMEMORY;
|
||||
goto cleanup_dynbuf;
|
||||
}
|
||||
ret = dns_rdata_tostruct(rdata, msg->tsig, mctx);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_tsig;
|
||||
|
||||
dns_message_takebuffer(msg, &dynbuf);
|
||||
|
||||
owner = NULL;
|
||||
ret = dns_message_gettempname(msg, &owner);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_tsig;
|
||||
goto cleanup_dynbuf;
|
||||
dns_name_toregion(&key->name, &r);
|
||||
dynbuf = NULL;
|
||||
ret = isc_buffer_allocate(mctx, &dynbuf, r.length);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_tsig;
|
||||
goto cleanup_dynbuf;
|
||||
isc_buffer_availableregion(dynbuf, &r2);
|
||||
memcpy(r2.base, r.base, r.length);
|
||||
dns_name_init(owner, NULL);
|
||||
@@ -512,7 +512,7 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
datalist = NULL;
|
||||
ret = dns_message_gettemprdatalist(msg, &datalist);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_tsig;
|
||||
goto cleanup_dynbuf;
|
||||
datalist->rdclass = dns_rdataclass_any;
|
||||
datalist->type = dns_rdatatype_tsig;
|
||||
datalist->covers = 0;
|
||||
@@ -522,7 +522,7 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
dataset = NULL;
|
||||
ret = dns_message_gettemprdataset(msg, &dataset);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_tsig;
|
||||
goto cleanup_dynbuf;
|
||||
dns_rdataset_init(dataset);
|
||||
dns_rdatalist_tordataset(datalist, dataset);
|
||||
msg->tsigset = dataset;
|
||||
@@ -530,9 +530,6 @@ dns_tsig_sign(dns_message_t *msg) {
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_tsig:
|
||||
dns_rdata_freestruct(msg->tsig);
|
||||
isc_mem_put(mctx, msg->tsig, sizeof *msg->tsig);
|
||||
cleanup_dynbuf:
|
||||
if (dynbuf != NULL)
|
||||
isc_buffer_free(&dynbuf);
|
||||
@@ -542,11 +539,6 @@ cleanup_signature:
|
||||
cleanup_other:
|
||||
if (tsig.other != NULL)
|
||||
isc_mem_put(mctx, tsig.other, tsig.otherlen);
|
||||
cleanup_algorithm:
|
||||
if (!algfreed)
|
||||
dns_name_free(&tsig.algorithm, mctx);
|
||||
cleanup_struct:
|
||||
msg->tsig = NULL;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -555,7 +547,7 @@ isc_result_t
|
||||
dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
dns_tsig_keyring_t *sring, dns_tsig_keyring_t *dring)
|
||||
{
|
||||
dns_rdata_any_tsig_t *tsig;
|
||||
dns_rdata_any_tsig_t tsig, querytsig;
|
||||
isc_region_t r, source_r, header_r, sig_r;
|
||||
isc_buffer_t databuf;
|
||||
unsigned char data[32];
|
||||
@@ -572,7 +564,6 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
|
||||
REQUIRE(source != NULL);
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->tsig == NULL);
|
||||
tsigkey = dns_message_gettsigkey(msg);
|
||||
REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey));
|
||||
|
||||
@@ -592,7 +583,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
* shouldn't be one on the response.
|
||||
*/
|
||||
if (is_response(msg) &&
|
||||
(tsigkey == NULL || msg->querytsig == NULL))
|
||||
(tsigkey == NULL || msg->querytsigset == NULL))
|
||||
return (DNS_R_UNEXPECTEDTSIG);
|
||||
|
||||
mctx = msg->mctx;
|
||||
@@ -607,21 +598,25 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
dns_rdataset_current(msg->tsigset, &rdata);
|
||||
tsig = (dns_rdata_any_tsig_t *)
|
||||
isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
|
||||
if (tsig == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
msg->tsig = tsig;
|
||||
ret = dns_rdata_tostruct(&rdata, tsig, mctx);
|
||||
ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_emptystruct;
|
||||
return (ret);
|
||||
if (is_response(msg)) {
|
||||
ret = dns_rdataset_first(msg->querytsigset);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
dns_rdataset_current(msg->querytsigset, &rdata);
|
||||
ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the key name and algorithm match that of the query?
|
||||
*/
|
||||
if (is_response(msg) &&
|
||||
(!dns_name_equal(keyname, &tsigkey->name) ||
|
||||
!dns_name_equal(&tsig->algorithm, &msg->querytsig->algorithm)))
|
||||
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm)))
|
||||
{
|
||||
msg->tsigstatus = dns_tsigerror_badkey;
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
@@ -639,22 +634,20 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
ret = ISC_R_NOTFOUND;
|
||||
if (sring != NULL)
|
||||
ret = dns_tsigkey_find(&tsigkey, keyname,
|
||||
&tsig->algorithm, sring);
|
||||
&tsig.algorithm, sring);
|
||||
if (ret == ISC_R_NOTFOUND && dring != NULL)
|
||||
ret = dns_tsigkey_find(&tsigkey, keyname,
|
||||
&tsig->algorithm, dring);
|
||||
&tsig.algorithm, dring);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
if (dring == NULL) {
|
||||
ret = DNS_R_TSIGVERIFYFAILURE;
|
||||
goto cleanup_struct;
|
||||
}
|
||||
if (dring == NULL)
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
msg->tsigstatus = dns_tsigerror_badkey;
|
||||
ret = dns_tsigkey_create(keyname, &tsig->algorithm,
|
||||
ret = dns_tsigkey_create(keyname, &tsig.algorithm,
|
||||
NULL, 0, ISC_FALSE, NULL,
|
||||
now, now,
|
||||
mctx, dring, &msg->tsigkey);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
}
|
||||
msg->tsigkey = tsigkey;
|
||||
@@ -665,14 +658,14 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
/*
|
||||
* Is the time ok?
|
||||
*/
|
||||
if (abs(now - tsig->timesigned) > tsig->fudge) {
|
||||
if (abs(now - tsig.timesigned) > tsig.fudge) {
|
||||
msg->tsigstatus = dns_tsigerror_badtime;
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
}
|
||||
|
||||
if (tsig->siglen > 0) {
|
||||
sig_r.base = tsig->signature;
|
||||
sig_r.length = tsig->siglen;
|
||||
if (tsig.siglen > 0) {
|
||||
sig_r.base = tsig.signature;
|
||||
sig_r.length = tsig.siglen;
|
||||
|
||||
ret = dst_key_verify(DST_SIGMODE_INIT, key, &ctx, NULL,
|
||||
&sig_r);
|
||||
@@ -681,15 +674,15 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
|
||||
if (is_response(msg)) {
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
|
||||
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
|
||||
NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_key;
|
||||
if (msg->querytsig->siglen > 0) {
|
||||
r.length = msg->querytsig->siglen;
|
||||
r.base = msg->querytsig->signature;
|
||||
if (querytsig.siglen > 0) {
|
||||
r.length = querytsig.siglen;
|
||||
r.base = querytsig.signature;
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key,
|
||||
&ctx, &r, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
@@ -714,7 +707,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
/*
|
||||
* Put in the original id.
|
||||
*/
|
||||
id = htons(tsig->originalid);
|
||||
id = htons(tsig.originalid);
|
||||
memcpy(&header[0], &id, 2);
|
||||
|
||||
/*
|
||||
@@ -748,7 +741,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
goto cleanup_key;
|
||||
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_putuint16(&databuf, tsig->common.rdclass);
|
||||
isc_buffer_putuint16(&databuf, tsig.common.rdclass);
|
||||
isc_buffer_putuint32(&databuf, msg->tsigset->ttl);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
|
||||
@@ -766,20 +759,20 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
goto cleanup_key;
|
||||
|
||||
isc_buffer_clear(&databuf);
|
||||
isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
|
||||
isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig.timesigned
|
||||
>> 32));
|
||||
isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
|
||||
isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig.timesigned
|
||||
& 0xFFFFFFFF));
|
||||
isc_buffer_putuint16(&databuf, tsig->fudge);
|
||||
isc_buffer_putuint16(&databuf, tsig->error);
|
||||
isc_buffer_putuint16(&databuf, tsig->otherlen);
|
||||
isc_buffer_putuint16(&databuf, tsig.fudge);
|
||||
isc_buffer_putuint16(&databuf, tsig.error);
|
||||
isc_buffer_putuint16(&databuf, tsig.otherlen);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
|
||||
&sig_r);
|
||||
|
||||
if (tsig->otherlen > 0) {
|
||||
r.base = tsig->other;
|
||||
r.length = tsig->otherlen;
|
||||
if (tsig.otherlen > 0) {
|
||||
r.base = tsig.other;
|
||||
r.length = tsig.otherlen;
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &ctx, &r,
|
||||
&sig_r);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
@@ -795,8 +788,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
else if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_key;
|
||||
}
|
||||
else if (tsig->error != dns_tsigerror_badsig &&
|
||||
tsig->error != dns_tsigerror_badkey)
|
||||
else if (tsig.error != dns_tsigerror_badsig &&
|
||||
tsig.error != dns_tsigerror_badkey)
|
||||
{
|
||||
msg->tsigstatus = dns_tsigerror_badsig;
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
@@ -804,7 +797,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
|
||||
msg->tsigstatus = dns_rcode_noerror;
|
||||
|
||||
if (tsig->error != dns_rcode_noerror) {
|
||||
if (tsig.error != dns_rcode_noerror) {
|
||||
if (is_response(msg)) {
|
||||
/* XXXBEW Log a message */
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -820,17 +813,13 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
|
||||
cleanup_key:
|
||||
if (dns_tsigkey_empty(tsigkey))
|
||||
dns_tsigkey_detach(&tsigkey);
|
||||
cleanup_struct:
|
||||
dns_rdata_freestruct(tsig);
|
||||
cleanup_emptystruct:
|
||||
msg->tsig = NULL;
|
||||
isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
dns_rdata_any_tsig_t *tsig = NULL;
|
||||
dns_rdata_any_tsig_t tsig, querytsig;
|
||||
isc_region_t r, source_r, header_r, sig_r;
|
||||
isc_buffer_t databuf;
|
||||
unsigned char data[32];
|
||||
@@ -847,11 +836,10 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
|
||||
REQUIRE(source != NULL);
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(msg->tsig == NULL);
|
||||
REQUIRE(dns_message_gettsigkey(msg) != NULL);
|
||||
REQUIRE(msg->tcp_continuation == 1);
|
||||
REQUIRE(is_response(msg));
|
||||
REQUIRE(msg->querytsig != NULL);
|
||||
REQUIRE(msg->querytsigset != NULL);
|
||||
|
||||
mctx = msg->mctx;
|
||||
|
||||
@@ -865,21 +853,22 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
dns_rdataset_current(msg->tsigset, &rdata);
|
||||
tsig = (dns_rdata_any_tsig_t *)
|
||||
isc_mem_get(mctx, sizeof(dns_rdata_any_tsig_t));
|
||||
if (tsig == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
msg->tsig = tsig;
|
||||
ret = dns_rdata_tostruct(&rdata, tsig, mctx);
|
||||
ret = dns_rdata_tostruct(&rdata, &tsig, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_emptystruct;
|
||||
return (ret);
|
||||
ret = dns_rdataset_first(msg->querytsigset);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
dns_rdataset_current(msg->querytsigset, &rdata);
|
||||
ret = dns_rdata_tostruct(&rdata, &querytsig, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Do the key name and algorithm match that of the query?
|
||||
*/
|
||||
if (!dns_name_equal(keyname, &tsigkey->name) ||
|
||||
!dns_name_equal(&tsig->algorithm,
|
||||
&msg->querytsig->algorithm))
|
||||
!dns_name_equal(&tsig.algorithm, &querytsig.algorithm))
|
||||
{
|
||||
msg->tsigstatus = dns_tsigerror_badkey;
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
@@ -889,7 +878,7 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
* Is the time ok?
|
||||
*/
|
||||
isc_stdtime_get(&now);
|
||||
if (abs(now - tsig->timesigned) > tsig->fudge) {
|
||||
if (abs(now - tsig.timesigned) > tsig.fudge) {
|
||||
msg->tsigstatus = dns_tsigerror_badtime;
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
}
|
||||
@@ -901,22 +890,22 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
ret = dst_key_verify(DST_SIGMODE_INIT, key, &msg->tsigctx,
|
||||
NULL, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_putuint16(&databuf, msg->querytsig->siglen);
|
||||
isc_buffer_putuint16(&databuf, querytsig.siglen);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx,
|
||||
&r, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
if (msg->querytsig->siglen > 0) {
|
||||
r.length = msg->querytsig->siglen;
|
||||
r.base = msg->querytsig->signature;
|
||||
return (ret);
|
||||
if (querytsig.siglen > 0) {
|
||||
r.length = querytsig.siglen;
|
||||
r.base = querytsig.signature;
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key,
|
||||
&msg->tsigctx, &r, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,8 +929,8 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
* Put in the original id.
|
||||
*/
|
||||
/* XXX Can TCP transfers be forwarded? How would that work? */
|
||||
if (tsig != NULL) {
|
||||
id = htons(tsig->originalid);
|
||||
if (has_tsig) {
|
||||
id = htons(tsig.originalid);
|
||||
memcpy(&header[0], &id, 2);
|
||||
}
|
||||
|
||||
@@ -953,7 +942,7 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &header_r,
|
||||
NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Digest all non-TSIG records.
|
||||
@@ -966,30 +955,30 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
r.length = source_r.length - DNS_MESSAGE_HEADERLEN;
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx, &r, NULL);
|
||||
if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Digest the time signed and fudge.
|
||||
*/
|
||||
if (has_tsig) {
|
||||
isc_buffer_init(&databuf, data, sizeof(data));
|
||||
isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig->timesigned
|
||||
isc_buffer_putuint16(&databuf, (isc_uint16_t)(tsig.timesigned
|
||||
>> 32));
|
||||
isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig->timesigned
|
||||
isc_buffer_putuint32(&databuf, (isc_uint32_t)(tsig.timesigned
|
||||
& 0xFFFFFFFF));
|
||||
isc_buffer_putuint16(&databuf, tsig->fudge);
|
||||
isc_buffer_putuint16(&databuf, tsig.fudge);
|
||||
isc_buffer_usedregion(&databuf, &r);
|
||||
ret = dst_key_verify(DST_SIGMODE_UPDATE, key, &msg->tsigctx,
|
||||
&r, NULL);
|
||||
|
||||
sig_r.base = tsig->signature;
|
||||
sig_r.length = tsig->siglen;
|
||||
if (tsig->siglen == 0) {
|
||||
if (tsig->error != dns_rcode_noerror)
|
||||
sig_r.base = tsig.signature;
|
||||
sig_r.length = tsig.siglen;
|
||||
if (tsig.siglen == 0) {
|
||||
if (tsig.error != dns_rcode_noerror)
|
||||
ret = DNS_R_TSIGERRORSET;
|
||||
else
|
||||
ret = DNS_R_TSIGVERIFYFAILURE;
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ret = dst_key_verify(DST_SIGMODE_FINAL, key, &msg->tsigctx,
|
||||
@@ -999,20 +988,13 @@ dns_tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
|
||||
return (DNS_R_TSIGVERIFYFAILURE);
|
||||
}
|
||||
else if (ret != ISC_R_SUCCESS)
|
||||
goto cleanup_struct;
|
||||
return (ret);
|
||||
|
||||
msg->tsigctx = NULL;
|
||||
}
|
||||
|
||||
msg->tsigstatus = dns_rcode_noerror;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup_struct:
|
||||
dns_rdata_freestruct(tsig);
|
||||
cleanup_emptystruct:
|
||||
msg->tsig = NULL;
|
||||
isc_mem_put(mctx, tsig, sizeof(dns_rdata_any_tsig_t));
|
||||
return (ret);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrin.c,v 1.73 2000/05/26 00:38:12 gson Exp $ */
|
||||
/* $Id: xfrin.c,v 1.74 2000/05/30 23:14:55 bwelling Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -132,7 +132,7 @@ struct dns_xfrin_ctx {
|
||||
unsigned int nmsg; /* Number of messages recvd */
|
||||
|
||||
dns_tsigkey_t *tsigkey; /* Key used to create TSIG */
|
||||
dns_rdata_any_tsig_t *lasttsig; /* The last TSIG */
|
||||
isc_buffer_t *lasttsig; /* The last TSIG */
|
||||
void *tsigctx; /* TSIG verification context */
|
||||
unsigned int sincetsig; /* recvd since the last TSIG */
|
||||
dns_xfrindone_t done;
|
||||
@@ -853,8 +853,7 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) {
|
||||
/*
|
||||
* Save the query TSIG and don't let message_destroy free it.
|
||||
*/
|
||||
xfr->lasttsig = msg->tsig;
|
||||
msg->tsig = NULL;
|
||||
CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
|
||||
|
||||
isc_buffer_usedregion(&xfr->qbuffer, ®ion);
|
||||
INSIST(region.length <= 65535);
|
||||
@@ -946,6 +945,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
dns_message_t *msg = NULL;
|
||||
dns_name_t *name;
|
||||
dns_tcpmsg_t *tcpmsg;
|
||||
dns_name_t *tsigowner = NULL;
|
||||
|
||||
REQUIRE(VALID_XFRIN(xfr));
|
||||
|
||||
@@ -971,7 +971,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg));
|
||||
|
||||
dns_message_settsigkey(msg, xfr->tsigkey);
|
||||
msg->querytsig = xfr->lasttsig;
|
||||
dns_message_setquerytsig(msg, xfr->lasttsig);
|
||||
msg->tsigctx = xfr->tsigctx;
|
||||
if (xfr->nmsg > 0)
|
||||
msg->tcp_continuation = 1;
|
||||
@@ -1030,7 +1030,7 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
if (result != ISC_R_NOMORE)
|
||||
goto failure;
|
||||
|
||||
if (msg->tsig != NULL) {
|
||||
if (dns_message_gettsig(msg, &tsigowner) != NULL) {
|
||||
/*
|
||||
* Reset the counter.
|
||||
*/
|
||||
@@ -1039,21 +1039,14 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
/*
|
||||
* Free the last tsig, if there is one.
|
||||
*/
|
||||
if (xfr->lasttsig != NULL) {
|
||||
dns_rdata_freestruct(xfr->lasttsig);
|
||||
isc_mem_put(xfr->mctx, xfr->lasttsig,
|
||||
sizeof(*xfr->lasttsig));
|
||||
}
|
||||
if (xfr->lasttsig != NULL)
|
||||
isc_buffer_free(&xfr->lasttsig);
|
||||
|
||||
/*
|
||||
* Update the last tsig pointer.
|
||||
*/
|
||||
xfr->lasttsig = msg->tsig;
|
||||
CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));
|
||||
|
||||
/*
|
||||
* Reset msg->tsig so it doesn't get freed.
|
||||
*/
|
||||
msg->tsig = NULL;
|
||||
} else if (dns_message_gettsigkey(msg) != NULL) {
|
||||
xfr->sincetsig++;
|
||||
if (xfr->sincetsig > 100 ||
|
||||
@@ -1069,11 +1062,6 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
*/
|
||||
xfr->nmsg++;
|
||||
|
||||
/*
|
||||
* Reset msg->querytsig so it doesn't get freed.
|
||||
*/
|
||||
msg->querytsig = NULL;
|
||||
|
||||
/*
|
||||
* Copy the context back.
|
||||
*/
|
||||
@@ -1110,10 +1098,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
|
||||
return;
|
||||
|
||||
failure:
|
||||
if (msg != NULL) {
|
||||
msg->querytsig = NULL;
|
||||
if (msg != NULL)
|
||||
dns_message_destroy(&msg);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS)
|
||||
xfrin_fail(xfr, result, "receiving responses");
|
||||
}
|
||||
@@ -1153,10 +1139,8 @@ maybe_free(dns_xfrin_ctx_t *xfr) {
|
||||
if (xfr->task != NULL)
|
||||
isc_task_detach(&xfr->task);
|
||||
|
||||
if (xfr->lasttsig != NULL) {
|
||||
dns_rdata_freestruct(xfr->lasttsig);
|
||||
isc_mem_put(xfr->mctx, xfr->lasttsig, sizeof(*xfr->lasttsig));
|
||||
}
|
||||
if (xfr->lasttsig != NULL)
|
||||
isc_buffer_free(&xfr->lasttsig);
|
||||
|
||||
dns_diff_clear(&xfr->diff);
|
||||
|
||||
|
Reference in New Issue
Block a user