summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/isccc/cc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/isccc/cc.c')
-rw-r--r--contrib/bind9/lib/isccc/cc.c818
1 files changed, 0 insertions, 818 deletions
diff --git a/contrib/bind9/lib/isccc/cc.c b/contrib/bind9/lib/isccc/cc.c
deleted file mode 100644
index e65349e..0000000
--- a/contrib/bind9/lib/isccc/cc.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
- * Portions Copyright (C) 2001-2003 Internet Software Consortium.
- * Portions Copyright (C) 2001 Nominum, 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 ISC AND NOMINUM 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: cc.c,v 1.10.18.5 2006/12/07 23:57:58 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <isc/assertions.h>
-#include <isc/hmacmd5.h>
-#include <isc/print.h>
-#include <isc/stdlib.h>
-
-#include <isccc/alist.h>
-#include <isccc/base64.h>
-#include <isccc/cc.h>
-#include <isccc/result.h>
-#include <isccc/sexpr.h>
-#include <isccc/symtab.h>
-#include <isccc/symtype.h>
-#include <isccc/util.h>
-
-#define MAX_TAGS 256
-#define DUP_LIFETIME 900
-
-typedef isccc_sexpr_t *sexpr_ptr;
-
-static unsigned char auth_hmd5[] = {
- 0x05, 0x5f, 0x61, 0x75, 0x74, 0x68, /*%< len + _auth */
- ISCCC_CCMSGTYPE_TABLE, /*%< message type */
- 0x00, 0x00, 0x00, 0x20, /*%< length == 32 */
- 0x04, 0x68, 0x6d, 0x64, 0x35, /*%< len + hmd5 */
- ISCCC_CCMSGTYPE_BINARYDATA, /*%< message type */
- 0x00, 0x00, 0x00, 0x16, /*%< length == 22 */
- /*
- * The base64 encoding of one of our HMAC-MD5 signatures is
- * 22 bytes.
- */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-#define HMD5_OFFSET 21 /*%< 21 = 6 + 1 + 4 + 5 + 1 + 4 */
-#define HMD5_LENGTH 22
-
-static isc_result_t
-table_towire(isccc_sexpr_t *alist, isccc_region_t *target);
-
-static isc_result_t
-list_towire(isccc_sexpr_t *alist, isccc_region_t *target);
-
-static isc_result_t
-value_towire(isccc_sexpr_t *elt, isccc_region_t *target)
-{
- size_t len;
- unsigned char *lenp;
- isccc_region_t *vr;
- isc_result_t result;
-
- if (isccc_sexpr_binaryp(elt)) {
- vr = isccc_sexpr_tobinary(elt);
- len = REGION_SIZE(*vr);
- if (REGION_SIZE(*target) < 1 + 4 + len)
- return (ISC_R_NOSPACE);
- PUT8(ISCCC_CCMSGTYPE_BINARYDATA, target->rstart);
- PUT32(len, target->rstart);
- if (REGION_SIZE(*target) < len)
- return (ISC_R_NOSPACE);
- PUT_MEM(vr->rstart, len, target->rstart);
- } else if (isccc_alist_alistp(elt)) {
- if (REGION_SIZE(*target) < 1 + 4)
- return (ISC_R_NOSPACE);
- PUT8(ISCCC_CCMSGTYPE_TABLE, target->rstart);
- /*
- * Emit a placeholder length.
- */
- lenp = target->rstart;
- PUT32(0, target->rstart);
- /*
- * Emit the table.
- */
- result = table_towire(elt, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- len = (size_t)(target->rstart - lenp);
- /*
- * 'len' is 4 bytes too big, since it counts
- * the placeholder length too. Adjust and
- * emit.
- */
- INSIST(len >= 4U);
- len -= 4;
- PUT32(len, lenp);
- } else if (isccc_sexpr_listp(elt)) {
- if (REGION_SIZE(*target) < 1 + 4)
- return (ISC_R_NOSPACE);
- PUT8(ISCCC_CCMSGTYPE_LIST, target->rstart);
- /*
- * Emit a placeholder length and count.
- */
- lenp = target->rstart;
- PUT32(0, target->rstart);
- /*
- * Emit the list.
- */
- result = list_towire(elt, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- len = (size_t)(target->rstart - lenp);
- /*
- * 'len' is 4 bytes too big, since it counts
- * the placeholder length. Adjust and emit.
- */
- INSIST(len >= 4U);
- len -= 4;
- PUT32(len, lenp);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-table_towire(isccc_sexpr_t *alist, isccc_region_t *target)
-{
- isccc_sexpr_t *kv, *elt, *k, *v;
- char *ks;
- isc_result_t result;
- size_t len;
-
- for (elt = isccc_alist_first(alist);
- elt != NULL;
- elt = ISCCC_SEXPR_CDR(elt)) {
- kv = ISCCC_SEXPR_CAR(elt);
- k = ISCCC_SEXPR_CAR(kv);
- ks = isccc_sexpr_tostring(k);
- v = ISCCC_SEXPR_CDR(kv);
- len = strlen(ks);
- INSIST(len <= 255U);
- /*
- * Emit the key name.
- */
- if (REGION_SIZE(*target) < 1 + len)
- return (ISC_R_NOSPACE);
- PUT8(len, target->rstart);
- PUT_MEM(ks, len, target->rstart);
- /*
- * Emit the value.
- */
- result = value_towire(v, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-list_towire(isccc_sexpr_t *list, isccc_region_t *target)
-{
- isc_result_t result;
-
- while (list != NULL) {
- result = value_towire(ISCCC_SEXPR_CAR(list), target);
- if (result != ISC_R_SUCCESS)
- return (result);
- list = ISCCC_SEXPR_CDR(list);
- }
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-sign(unsigned char *data, unsigned int length, unsigned char *hmd5,
- isccc_region_t *secret)
-{
- isc_hmacmd5_t ctx;
- isc_result_t result;
- isccc_region_t source, target;
- unsigned char digest[ISC_MD5_DIGESTLENGTH];
- unsigned char digestb64[ISC_MD5_DIGESTLENGTH * 4];
-
- isc_hmacmd5_init(&ctx, secret->rstart, REGION_SIZE(*secret));
- isc_hmacmd5_update(&ctx, data, length);
- isc_hmacmd5_sign(&ctx, digest);
- source.rstart = digest;
- source.rend = digest + ISC_MD5_DIGESTLENGTH;
- target.rstart = digestb64;
- target.rend = digestb64 + ISC_MD5_DIGESTLENGTH * 4;
- result = isccc_base64_encode(&source, 64, "", &target);
- if (result != ISC_R_SUCCESS)
- return (result);
- PUT_MEM(digestb64, HMD5_LENGTH, hmd5);
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isccc_cc_towire(isccc_sexpr_t *alist, isccc_region_t *target,
- isccc_region_t *secret)
-{
- unsigned char *hmd5_rstart, *signed_rstart;
- isc_result_t result;
-
- if (REGION_SIZE(*target) < 4 + sizeof(auth_hmd5))
- return (ISC_R_NOSPACE);
- /*
- * Emit protocol version.
- */
- PUT32(1, target->rstart);
- if (secret != NULL) {
- /*
- * Emit _auth section with zeroed HMAC-MD5 signature.
- * We'll replace the zeros with the real signature once
- * we know what it is.
- */
- hmd5_rstart = target->rstart + HMD5_OFFSET;
- PUT_MEM(auth_hmd5, sizeof(auth_hmd5), target->rstart);
- } else
- hmd5_rstart = NULL;
- signed_rstart = target->rstart;
- /*
- * Delete any existing _auth section so that we don't try
- * to encode it.
- */
- isccc_alist_delete(alist, "_auth");
- /*
- * Emit the message.
- */
- result = table_towire(alist, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- if (secret != NULL)
- return (sign(signed_rstart, (target->rstart - signed_rstart),
- hmd5_rstart, secret));
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
- isccc_region_t *secret)
-{
- isc_hmacmd5_t ctx;
- isccc_region_t source;
- isccc_region_t target;
- isc_result_t result;
- isccc_sexpr_t *_auth, *hmd5;
- unsigned char digest[ISC_MD5_DIGESTLENGTH];
- unsigned char digestb64[ISC_MD5_DIGESTLENGTH * 4];
-
- /*
- * Extract digest.
- */
- _auth = isccc_alist_lookup(alist, "_auth");
- if (_auth == NULL)
- return (ISC_R_FAILURE);
- hmd5 = isccc_alist_lookup(_auth, "hmd5");
- if (hmd5 == NULL)
- return (ISC_R_FAILURE);
- /*
- * Compute digest.
- */
- isc_hmacmd5_init(&ctx, secret->rstart, REGION_SIZE(*secret));
- isc_hmacmd5_update(&ctx, data, length);
- isc_hmacmd5_sign(&ctx, digest);
- source.rstart = digest;
- source.rend = digest + ISC_MD5_DIGESTLENGTH;
- target.rstart = digestb64;
- target.rend = digestb64 + ISC_MD5_DIGESTLENGTH * 4;
- result = isccc_base64_encode(&source, 64, "", &target);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Strip trailing == and NUL terminate target.
- */
- target.rstart -= 2;
- *target.rstart++ = '\0';
- /*
- * Verify.
- */
- if (strcmp((char *)digestb64, isccc_sexpr_tostring(hmd5)) != 0)
- return (ISCCC_R_BADAUTH);
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-table_fromwire(isccc_region_t *source, isccc_region_t *secret,
- isccc_sexpr_t **alistp);
-
-static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp);
-
-static isc_result_t
-value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep)
-{
- unsigned int msgtype;
- isc_uint32_t len;
- isccc_sexpr_t *value;
- isccc_region_t active;
- isc_result_t result;
-
- if (REGION_SIZE(*source) < 1 + 4)
- return (ISC_R_UNEXPECTEDEND);
- GET8(msgtype, source->rstart);
- GET32(len, source->rstart);
- if (REGION_SIZE(*source) < len)
- return (ISC_R_UNEXPECTEDEND);
- active.rstart = source->rstart;
- active.rend = active.rstart + len;
- source->rstart = active.rend;
- if (msgtype == ISCCC_CCMSGTYPE_BINARYDATA) {
- value = isccc_sexpr_frombinary(&active);
- if (value != NULL) {
- *valuep = value;
- result = ISC_R_SUCCESS;
- } else
- result = ISC_R_NOMEMORY;
- } else if (msgtype == ISCCC_CCMSGTYPE_TABLE)
- result = table_fromwire(&active, NULL, valuep);
- else if (msgtype == ISCCC_CCMSGTYPE_LIST)
- result = list_fromwire(&active, valuep);
- else
- result = ISCCC_R_SYNTAX;
-
- return (result);
-}
-
-static isc_result_t
-table_fromwire(isccc_region_t *source, isccc_region_t *secret,
- isccc_sexpr_t **alistp)
-{
- char key[256];
- isc_uint32_t len;
- isc_result_t result;
- isccc_sexpr_t *alist, *value;
- isc_boolean_t first_tag;
- unsigned char *checksum_rstart;
-
- REQUIRE(alistp != NULL && *alistp == NULL);
-
- checksum_rstart = NULL;
- first_tag = ISC_TRUE;
- alist = isccc_alist_create();
- if (alist == NULL)
- return (ISC_R_NOMEMORY);
-
- while (!REGION_EMPTY(*source)) {
- GET8(len, source->rstart);
- if (REGION_SIZE(*source) < len) {
- result = ISC_R_UNEXPECTEDEND;
- goto bad;
- }
- GET_MEM(key, len, source->rstart);
- key[len] = '\0'; /* Ensure NUL termination. */
- value = NULL;
- result = value_fromwire(source, &value);
- if (result != ISC_R_SUCCESS)
- goto bad;
- if (isccc_alist_define(alist, key, value) == NULL) {
- result = ISC_R_NOMEMORY;
- goto bad;
- }
- if (first_tag && secret != NULL && strcmp(key, "_auth") == 0)
- checksum_rstart = source->rstart;
- first_tag = ISC_FALSE;
- }
-
- *alistp = alist;
-
- if (secret != NULL) {
- if (checksum_rstart != NULL)
- return (verify(alist, checksum_rstart,
- (source->rend - checksum_rstart),
- secret));
- return (ISCCC_R_BADAUTH);
- }
-
- return (ISC_R_SUCCESS);
-
- bad:
- isccc_sexpr_free(&alist);
-
- return (result);
-}
-
-static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp)
-{
- isccc_sexpr_t *list, *value;
- isc_result_t result;
-
- list = NULL;
- while (!REGION_EMPTY(*source)) {
- value = NULL;
- result = value_fromwire(source, &value);
- if (result != ISC_R_SUCCESS) {
- isccc_sexpr_free(&list);
- return (result);
- }
- if (isccc_sexpr_addtolist(&list, value) == NULL) {
- isccc_sexpr_free(&value);
- isccc_sexpr_free(&list);
- return (result);
- }
- }
-
- *listp = list;
-
- return (ISC_R_SUCCESS);
-}
-
-isc_result_t
-isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp,
- isccc_region_t *secret)
-{
- unsigned int size;
- isc_uint32_t version;
-
- size = REGION_SIZE(*source);
- if (size < 4)
- return (ISC_R_UNEXPECTEDEND);
- GET32(version, source->rstart);
- if (version != 1)
- return (ISCCC_R_UNKNOWNVERSION);
-
- return (table_fromwire(source, secret, alistp));
-}
-
-static isc_result_t
-createmessage(isc_uint32_t version, const char *from, const char *to,
- isc_uint32_t serial, isccc_time_t now,
- isccc_time_t expires, isccc_sexpr_t **alistp,
- isc_boolean_t want_expires)
-{
- isccc_sexpr_t *alist, *_ctrl, *_data;
- isc_result_t result;
-
- REQUIRE(alistp != NULL && *alistp == NULL);
-
- if (version != 1)
- return (ISCCC_R_UNKNOWNVERSION);
-
- alist = isccc_alist_create();
- if (alist == NULL)
- return (ISC_R_NOMEMORY);
-
- result = ISC_R_NOMEMORY;
-
- _ctrl = isccc_alist_create();
- if (_ctrl == NULL)
- goto bad;
- if (isccc_alist_define(alist, "_ctrl", _ctrl) == NULL) {
- isccc_sexpr_free(&_ctrl);
- goto bad;
- }
-
- _data = isccc_alist_create();
- if (_data == NULL)
- goto bad;
- if (isccc_alist_define(alist, "_data", _data) == NULL) {
- isccc_sexpr_free(&_data);
- goto bad;
- }
-
- if (isccc_cc_defineuint32(_ctrl, "_ser", serial) == NULL ||
- isccc_cc_defineuint32(_ctrl, "_tim", now) == NULL ||
- (want_expires &&
- isccc_cc_defineuint32(_ctrl, "_exp", expires) == NULL))
- goto bad;
- if (from != NULL &&
- isccc_cc_definestring(_ctrl, "_frm", from) == NULL)
- goto bad;
- if (to != NULL &&
- isccc_cc_definestring(_ctrl, "_to", to) == NULL)
- goto bad;
-
- *alistp = alist;
-
- return (ISC_R_SUCCESS);
-
- bad:
- isccc_sexpr_free(&alist);
-
- return (result);
-}
-
-isc_result_t
-isccc_cc_createmessage(isc_uint32_t version, const char *from, const char *to,
- isc_uint32_t serial, isccc_time_t now,
- isccc_time_t expires, isccc_sexpr_t **alistp)
-{
- return (createmessage(version, from, to, serial, now, expires,
- alistp, ISC_TRUE));
-}
-
-isc_result_t
-isccc_cc_createack(isccc_sexpr_t *message, isc_boolean_t ok,
- isccc_sexpr_t **ackp)
-{
- char *_frm, *_to;
- isc_uint32_t serial;
- isccc_sexpr_t *ack, *_ctrl;
- isc_result_t result;
- isccc_time_t t;
-
- REQUIRE(ackp != NULL && *ackp == NULL);
-
- _ctrl = isccc_alist_lookup(message, "_ctrl");
- if (_ctrl == NULL ||
- isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
- isccc_cc_lookupuint32(_ctrl, "_tim", &t) != ISC_R_SUCCESS)
- return (ISC_R_FAILURE);
- /*
- * _frm and _to are optional.
- */
- _frm = NULL;
- (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm);
- _to = NULL;
- (void)isccc_cc_lookupstring(_ctrl, "_to", &_to);
- /*
- * Create the ack.
- */
- ack = NULL;
- result = createmessage(1, _to, _frm, serial, t, 0, &ack, ISC_FALSE);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- _ctrl = isccc_alist_lookup(ack, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_R_FAILURE);
- if (isccc_cc_definestring(ack, "_ack", (ok) ? "1" : "0") == NULL) {
- result = ISC_R_NOMEMORY;
- goto bad;
- }
-
- *ackp = ack;
-
- return (ISC_R_SUCCESS);
-
- bad:
- isccc_sexpr_free(&ack);
-
- return (result);
-}
-
-isc_boolean_t
-isccc_cc_isack(isccc_sexpr_t *message)
-{
- isccc_sexpr_t *_ctrl;
-
- _ctrl = isccc_alist_lookup(message, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_FALSE);
- if (isccc_cc_lookupstring(_ctrl, "_ack", NULL) == ISC_R_SUCCESS)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_boolean_t
-isccc_cc_isreply(isccc_sexpr_t *message)
-{
- isccc_sexpr_t *_ctrl;
-
- _ctrl = isccc_alist_lookup(message, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_FALSE);
- if (isccc_cc_lookupstring(_ctrl, "_rpl", NULL) == ISC_R_SUCCESS)
- return (ISC_TRUE);
- return (ISC_FALSE);
-}
-
-isc_result_t
-isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now,
- isccc_time_t expires, isccc_sexpr_t **alistp)
-{
- char *_frm, *_to, *type;
- isc_uint32_t serial;
- isccc_sexpr_t *alist, *_ctrl, *_data;
- isc_result_t result;
-
- REQUIRE(alistp != NULL && *alistp == NULL);
-
- _ctrl = isccc_alist_lookup(message, "_ctrl");
- _data = isccc_alist_lookup(message, "_data");
- if (_ctrl == NULL ||
- _data == NULL ||
- isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
- isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS)
- return (ISC_R_FAILURE);
- /*
- * _frm and _to are optional.
- */
- _frm = NULL;
- (void)isccc_cc_lookupstring(_ctrl, "_frm", &_frm);
- _to = NULL;
- (void)isccc_cc_lookupstring(_ctrl, "_to", &_to);
- /*
- * Create the response.
- */
- alist = NULL;
- result = isccc_cc_createmessage(1, _to, _frm, serial, now, expires,
- &alist);
- if (result != ISC_R_SUCCESS)
- return (result);
- _ctrl = isccc_alist_lookup(alist, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_R_FAILURE);
- _data = isccc_alist_lookup(alist, "_data");
- if (_data == NULL)
- return (ISC_R_FAILURE);
- if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL ||
- isccc_cc_definestring(_data, "type", type) == NULL) {
- isccc_sexpr_free(&alist);
- return (ISC_R_NOMEMORY);
- }
-
- *alistp = alist;
-
- return (ISC_R_SUCCESS);
-}
-
-isccc_sexpr_t *
-isccc_cc_definestring(isccc_sexpr_t *alist, const char *key, const char *str)
-{
- size_t len;
- isccc_region_t r;
-
- len = strlen(str);
- DE_CONST(str, r.rstart);
- r.rend = r.rstart + len;
-
- return (isccc_alist_definebinary(alist, key, &r));
-}
-
-isccc_sexpr_t *
-isccc_cc_defineuint32(isccc_sexpr_t *alist, const char *key, isc_uint32_t i)
-{
- char b[100];
- size_t len;
- isccc_region_t r;
-
- snprintf(b, sizeof(b), "%u", i);
- len = strlen(b);
- r.rstart = (unsigned char *)b;
- r.rend = (unsigned char *)b + len;
-
- return (isccc_alist_definebinary(alist, key, &r));
-}
-
-isc_result_t
-isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp)
-{
- isccc_sexpr_t *kv, *v;
-
- kv = isccc_alist_assq(alist, key);
- if (kv != NULL) {
- v = ISCCC_SEXPR_CDR(kv);
- if (isccc_sexpr_binaryp(v)) {
- if (strp != NULL)
- *strp = isccc_sexpr_tostring(v);
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_EXISTS);
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-isc_result_t
-isccc_cc_lookupuint32(isccc_sexpr_t *alist, const char *key,
- isc_uint32_t *uintp)
-{
- isccc_sexpr_t *kv, *v;
-
- kv = isccc_alist_assq(alist, key);
- if (kv != NULL) {
- v = ISCCC_SEXPR_CDR(kv);
- if (isccc_sexpr_binaryp(v)) {
- if (uintp != NULL)
- *uintp = (isc_uint32_t)
- strtoul(isccc_sexpr_tostring(v),
- NULL, 10);
- return (ISC_R_SUCCESS);
- } else
- return (ISC_R_EXISTS);
- }
-
- return (ISC_R_NOTFOUND);
-}
-
-static void
-symtab_undefine(char *key, unsigned int type, isccc_symvalue_t value,
- void *arg)
-{
- UNUSED(type);
- UNUSED(value);
- UNUSED(arg);
-
- free(key);
-}
-
-static isc_boolean_t
-symtab_clean(char *key, unsigned int type, isccc_symvalue_t value,
- void *arg)
-{
- isccc_time_t *now;
-
- UNUSED(key);
- UNUSED(type);
-
- now = arg;
-
- if (*now < value.as_uinteger)
- return (ISC_FALSE);
- if ((*now - value.as_uinteger) < DUP_LIFETIME)
- return (ISC_FALSE);
- return (ISC_TRUE);
-}
-
-isc_result_t
-isccc_cc_createsymtab(isccc_symtab_t **symtabp)
-{
- return (isccc_symtab_create(11897, symtab_undefine, NULL, ISC_FALSE,
- symtabp));
-}
-
-void
-isccc_cc_cleansymtab(isccc_symtab_t *symtab, isccc_time_t now)
-{
- isccc_symtab_foreach(symtab, symtab_clean, &now);
-}
-
-static isc_boolean_t
-has_whitespace(const char *str)
-{
- char c;
-
- if (str == NULL)
- return (ISC_FALSE);
- while ((c = *str++) != '\0') {
- if (c == ' ' || c == '\t' || c == '\n')
- return (ISC_TRUE);
- }
- return (ISC_FALSE);
-}
-
-isc_result_t
-isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message,
- isccc_time_t now)
-{
- const char *_frm;
- const char *_to;
- char *_ser, *_tim, *tmp;
- isc_result_t result;
- char *key;
- size_t len;
- isccc_symvalue_t value;
- isccc_sexpr_t *_ctrl;
-
- _ctrl = isccc_alist_lookup(message, "_ctrl");
- if (_ctrl == NULL ||
- isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS ||
- isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS)
- return (ISC_R_FAILURE);
- /*
- * _frm and _to are optional.
- */
- if (isccc_cc_lookupstring(_ctrl, "_frm", &tmp) != ISC_R_SUCCESS)
- _frm = "";
- else
- _frm = tmp;
- if (isccc_cc_lookupstring(_ctrl, "_to", &tmp) != ISC_R_SUCCESS)
- _to = "";
- else
- _to = tmp;
- /*
- * Ensure there is no newline in any of the strings. This is so
- * we can write them to a file later.
- */
- if (has_whitespace(_frm) || has_whitespace(_to) ||
- has_whitespace(_ser) || has_whitespace(_tim))
- return (ISC_R_FAILURE);
- len = strlen(_frm) + strlen(_to) + strlen(_ser) + strlen(_tim) + 4;
- key = malloc(len);
- if (key == NULL)
- return (ISC_R_NOMEMORY);
- snprintf(key, len, "%s;%s;%s;%s", _frm, _to, _ser, _tim);
- value.as_uinteger = now;
- result = isccc_symtab_define(symtab, key, ISCCC_SYMTYPE_CCDUP, value,
- isccc_symexists_reject);
- if (result != ISC_R_SUCCESS) {
- free(key);
- return (result);
- }
-
- return (ISC_R_SUCCESS);
-}
OpenPOWER on IntegriCloud