tsig.c revision 4dc6a937d699f76782c17d58305f6d6cfaa8b55d
/*
* Copyright (C) 1999 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM 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: tsig.c,v 1.3 1999/08/26 20:41:53 bwelling Exp $
* Principal Author: Brian Wellington
*/
#include <config.h>
#include <stdlib.h>
#include <isc/assertions.h>
#include <dns/keyvalues.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
/* XXXBEW If an unsorted list isn't good enough, this can be updated */
static isc_rwlock_t tsiglock;
{
isc_buffer_t b, nameb;
char namestr[1024];
if (length > 0)
return (ISC_R_NOTFOUND);
else
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
if (ret != ISC_R_SUCCESS)
goto cleanup_name;
if (ret != ISC_R_SUCCESS)
goto cleanup_algorithm;
if (length > 0) {
isc_buffer_add(&b, length);
if (ret != ISC_R_SUCCESS)
goto cleanup_algorithm;
}
else
return (ISC_R_SUCCESS);
return (ret);
}
/* Caller must be sure that this key is not in use. */
void
}
}
unsigned char data[128];
isc_region_t r;
int tries;
if (is_response(msg))
tsig = (dns_rdata_any_tsig_t *)
return (ISC_R_NOMEMORY);
goto cleanup_struct;
}
if (ret != ISC_R_SUCCESS)
goto cleanup_struct;
if (ret != ISC_R_SUCCESS)
goto cleanup_algorithm;
if (!dns_tsig_emptykey(key)) {
if (ret != ISC_R_SUCCESS)
goto cleanup_algorithm;
}
if (is_response(msg)) {
if (!dns_tsig_emptykey(key)) {
isc_buffer_available(&databuf, &r);
return (ISC_R_NOSPACE);
isc_buffer_used(&databuf, &r);
NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup_algorithm;
}
}
else
}
else {
goto cleanup_other;
}
}
if (!dns_tsig_emptykey(key)) {
unsigned char header[DNS_MESSAGE_HEADERLEN];
isc_buffer_used(&headerbuf, &r);
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
/* Digest the name, class, ttl, alg */
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
isc_buffer_used(&databuf, &r);
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
}
else {
querysigned >> 32);
querysigned & 0xFFFFFFFF);
}
isc_buffer_used(&databuf, &r);
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup_other;
}
goto cleanup_other;
}
&sigbuf);
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
}
else {
}
/* There should be a better way of accessing msg->scratchpad */
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
tries = 0;
while (tries < 2) {
if (ret == ISC_R_SUCCESS)
break;
else if (ret == ISC_R_NOSPACE) {
if (++tries == 2)
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
}
else
goto cleanup_signature;
}
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
if (ret != ISC_R_SUCCESS)
goto cleanup_signature;
return (ISC_R_SUCCESS);
return (ret);
}
unsigned char data[32];
unsigned char header[DNS_MESSAGE_HEADERLEN];
if (is_response(msg)) {
}
/*
* If we're here, we know the message is well formed and contains a
* TSIG record.
*/
if (ret != ISC_R_SUCCESS)
return (ret);
if (ret != ISC_R_SUCCESS)
return (ret);
tsig = (dns_rdata_any_tsig_t *)
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS)
goto cleanup_emptystruct;
isc_buffer_used(source, &r);
/* Do the key name and algorithm match that of the query? */
if (is_response(msg) &&
{
return (DNS_R_TSIGVERIFYFAILURE);
}
/* Find dns_tsig_key_t based on keyname */
if (ret != ISC_R_SUCCESS) {
/*
* this key must be deleted later - an empty key can be found
* by calling dns_tsig_emptykey()
*/
if (ret != ISC_R_SUCCESS)
goto cleanup_struct;
return (DNS_R_TSIGVERIFYFAILURE);
}
/* Is the time ok? */
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
return (DNS_R_TSIGVERIFYFAILURE);
}
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
if (is_response(msg)) {
isc_buffer_used(&databuf, &r);
NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
}
}
/* Decrement the additional field counter */
/* Put in the original id */
/* Digest the modified header */
&sig_r);
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
/* Digest all non-TSIG records. */
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
/* Digest the key name */
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
isc_buffer_used(&databuf, &r);
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
/* Digest the key algorithm */
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
isc_buffer_used(&databuf, &r);
&sig_r);
if (ret != ISC_R_SUCCESS)
goto cleanup_key;
}
if (ret == DST_R_VERIFY_FINAL_FAILURE) {
return (DNS_R_TSIGVERIFYFAILURE);
}
else if (ret != ISC_R_SUCCESS)
goto cleanup_key;
}
{
return (DNS_R_TSIGVERIFYFAILURE);
}
if (is_response(msg)) {
/* XXXBEW Log a message */
return (ISC_R_SUCCESS);
}
else
return (DNS_R_TSIGERRORSET);
}
return (ISC_R_SUCCESS);
}
return (ret);
}
{
{
return (ISC_R_SUCCESS);
}
}
return (ISC_R_NOTFOUND);
}
unsigned char data[32];
if (ret != ISC_R_SUCCESS) {
"isc_rwlock_init() failed: %s",
return (DNS_R_UNEXPECTED);
}
if (ret != ISC_R_SUCCESS)
return (ret);
if (dns_tsig_hmacmd5_name == NULL)
return (ISC_R_NOMEMORY);
if (ret != ISC_R_SUCCESS) {
return (ret);
}
return (ISC_R_SUCCESS);
}
void
dns_tsig_destroy() {
while (!ISC_LIST_EMPTY(tsigkeys)) {
}
}