cc.c revision ab023a65562e62b85a824509d829b6fad87e00b1
/*
* Portions Copyright (C) 2004 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.12 2005/04/27 04:57:25 sra Exp $ */
/*! \file */
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <isc/assertions.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_LENGTH 22
static isc_result_t
static isc_result_t
static isc_result_t
{
unsigned char *lenp;
if (isccc_sexpr_binaryp(elt)) {
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
} else if (isccc_alist_alistp(elt)) {
return (ISC_R_NOSPACE);
/*
* Emit a placeholder length.
*/
/*
* Emit the table.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* 'len' is 4 bytes too big, since it counts
* the placeholder length too. Adjust and
* emit.
*/
len -= 4;
} else if (isccc_sexpr_listp(elt)) {
return (ISC_R_NOSPACE);
/*
* Emit a placeholder length and count.
*/
/*
* Emit the list.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* 'len' is 4 bytes too big, since it counts
* the placeholder length. Adjust and emit.
*/
len -= 4;
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
char *ks;
k = ISCCC_SEXPR_CAR(kv);
ks = isccc_sexpr_tostring(k);
v = ISCCC_SEXPR_CDR(kv);
/*
* Emit the key name.
*/
return (ISC_R_NOSPACE);
/*
* Emit the value.
*/
if (result != ISC_R_SUCCESS)
return (result);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
if (result != ISC_R_SUCCESS)
return (result);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
unsigned char digest[ISC_MD5_DIGESTLENGTH];
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
}
{
unsigned char *hmd5_rstart, *signed_rstart;
return (ISC_R_NOSPACE);
/*
* Emit protocol version.
*/
/*
* Emit _auth section with zeroed HMAC-MD5 signature.
* We'll replace the zeros with the real signature once
* we know what it is.
*/
} else
hmd5_rstart = NULL;
/*
* Delete any existing _auth section so that we don't try
* to encode it.
*/
/*
* Emit the message.
*/
if (result != ISC_R_SUCCESS)
return (result);
hmd5_rstart, secret));
return (ISC_R_SUCCESS);
}
static isc_result_t
{
unsigned char digest[ISC_MD5_DIGESTLENGTH];
/*
* Extract digest.
*/
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
/*
* Compute digest.
*/
if (result != ISC_R_SUCCESS)
return (result);
/*
* Strip trailing == and NUL terminate target.
*/
/*
* Verify.
*/
return (ISCCC_R_BADAUTH);
return (ISC_R_SUCCESS);
}
static isc_result_t
isccc_sexpr_t **alistp);
static isc_result_t
static isc_result_t
{
unsigned int msgtype;
return (ISC_R_UNEXPECTEDEND);
return (ISC_R_UNEXPECTEDEND);
if (msgtype == ISCCC_CCMSGTYPE_BINARYDATA) {
} else
} else if (msgtype == ISCCC_CCMSGTYPE_TABLE)
else if (msgtype == ISCCC_CCMSGTYPE_LIST)
else
return (result);
}
static isc_result_t
{
char key[256];
unsigned char *checksum_rstart;
alist = isccc_alist_create();
return (ISC_R_NOMEMORY);
while (!REGION_EMPTY(*source)) {
goto bad;
}
if (result != ISC_R_SUCCESS)
goto bad;
goto bad;
}
}
if (checksum_rstart != NULL)
secret));
return (ISCCC_R_BADAUTH);
}
return (ISC_R_SUCCESS);
bad:
return (result);
}
static isc_result_t
{
while (!REGION_EMPTY(*source)) {
if (result != ISC_R_SUCCESS) {
return (result);
}
return (result);
}
}
return (ISC_R_SUCCESS);
}
{
unsigned int size;
if (size < 4)
return (ISC_R_UNEXPECTEDEND);
if (version != 1)
return (ISCCC_R_UNKNOWNVERSION);
}
static isc_result_t
{
if (version != 1)
return (ISCCC_R_UNKNOWNVERSION);
alist = isccc_alist_create();
return (ISC_R_NOMEMORY);
_ctrl = isccc_alist_create();
_data = isccc_alist_create();
goto bad;
goto bad;
(want_expires &&
goto bad;
goto bad;
goto bad;
return (ISC_R_SUCCESS);
bad:
return (result);
}
{
}
{
isccc_time_t t;
return (ISC_R_FAILURE);
/*
* _frm and _to are optional.
*/
/*
* Create the ack.
*/
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_FAILURE);
goto bad;
}
return (ISC_R_SUCCESS);
bad:
return (result);
}
{
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
}
{
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
}
{
return (ISC_R_FAILURE);
/*
* _frm and _to are optional.
*/
/*
* Create the response.
*/
&alist);
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
return (ISC_R_NOMEMORY);
}
return (ISC_R_SUCCESS);
}
{
}
{
char b[100];
snprintf(b, sizeof(b), "%u", i);
r.rstart = (unsigned char *)b;
}
{
isccc_sexpr_t *kv, *v;
v = ISCCC_SEXPR_CDR(kv);
if (isccc_sexpr_binaryp(v)) {
*strp = isccc_sexpr_tostring(v);
return (ISC_R_SUCCESS);
} else
return (ISC_R_EXISTS);
}
return (ISC_R_NOTFOUND);
}
{
isccc_sexpr_t *kv, *v;
v = ISCCC_SEXPR_CDR(kv);
if (isccc_sexpr_binaryp(v)) {
*uintp = (isc_uint32_t)
NULL, 10);
return (ISC_R_SUCCESS);
} else
return (ISC_R_EXISTS);
}
return (ISC_R_NOTFOUND);
}
static void
void *arg)
{
}
static isc_boolean_t
void *arg)
{
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
}
{
symtabp));
}
void
{
}
static isc_boolean_t
has_whitespace(const char *str)
{
char c;
return (ISC_FALSE);
while ((c = *str++) != '\0') {
if (c == ' ' || c == '\t' || c == '\n')
return (ISC_TRUE);
}
return (ISC_FALSE);
}
{
const char *_frm;
const char *_to;
char *key;
return (ISC_R_FAILURE);
/*
* _frm and _to are optional.
*/
_frm = "";
else
_to = "";
else
/*
* Ensure there is no newline in any of the strings. This is so
* we can write them to a file later.
*/
return (ISC_R_FAILURE);
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}