dnsval-2.0/0000775000237200023720000000000012111172621012764 5ustar hardakerhardakerdnsval-2.0/.cvsignore0000664000237200023720000000011710560656624015003 0ustar hardakerhardakerMakefile autom4te.cache config.log config.status libtool stamp-h libval-config dnsval-2.0/libval-config.in0000664000237200023720000001035210672531415016043 0ustar hardakerhardaker#!/bin/sh # srcdir=@srcdir@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sbindir=@sbindir@ libdir=@libdir@ datadir=@datadir@ includedir=@includedir@/validator mandir=@mandir@ lvc_PREFIX=$prefix lvc_EXEC_PREFIX=$exec_prefix lvc_INCLUDEDIR=$includedir lvc_DEVCFLAGS="@DEVFLAGS@" lvc_CFLAGS="@CFLAGS@" lvc_CPPFLAGS="@CPPFLAGS@" lvc_LDFLAGS="@LDFLAGS@" lvc_LIBS="@LIBS@" lvc_LIBDIR="-L${libdir}" LIBVAL_SUFFIX=@LIBVAL_SUFFIX@ lvc_RESOLV_CONF="@VAL_RESOLV_CONF@" lvc_ROOT_HINTS="@VAL_ROOT_HINTS@" lvc_DNSVAL="@VAL_CONFIGURATION_FILE@" if test "x$1" = "x"; then usage="yes" else while test "x$done" = "x" -a "x$1" != "x" -a "x$usage" != "xyes"; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in --prefix=*) prefix=$optarg lvc_PREFIX=${prefix} lvc_INCLUDEDIR=${prefix}/include lvc_LIBDIR=-L${prefix}/lib ;; --exec-prefix=*) exec_prefix=$optarg lvc_EXEC_PREFIX=${exec_prefix} lvc_LIBDIR=-L${exec_prefix}/lib ;; --configure-options|--con*) echo @CONFIGURE_OPTIONS@ ;; #################################################### compile --base-cflags) echo ${lvc_CFLAGS} ${lvc_CPPFLAGS} -I${lvc_INCLUDEDIR} ;; --cflags|--cf*) echo ${lvc_CFLAGS} ${lvc_DEVFLAGS} ${lvc_CPPFLAGS} -I. -I${lvc_INCLUDEDIR} ;; --srcdir) echo $lvc_SRCDIR ;; #################################################### linking --libdir|--lib-dir) echo $lvc_LIBDIR ;; --ldflags|--ld*) echo $lvc_LDFLAGS ;; #################################################### client lib --libs) # use this one == --libval-libs + --external-libs echo $lvc_LDFLAGS $lvc_LIBDIR -lsres -lval${LIBVAL_SUFFIX} $lvc_LIBS ;; --libval-libs) echo $lvc_LIBDIR -lsres -lval${LIBVAL_SUFFIX} ;; --external-libs) echo $lvc_LDFLAGS $lvc_LIBS ;; #################################################### --resolver-config|--res*) echo $lvc_RESOLV_CONF ;; --root-hints|--roo*) echo $lvc_ROOT_HINTS ;; --dnsval-config|--dns*) echo $lvc_DNSVAL ;; #################################################### --version|--ver*) echo @PACKAGE_VERSION@ ;; --help) usage="yes" ;; --prefix|--pre*) echo $lvc_PREFIX ;; --exec-prefix) echo $lvc_EXEC_PREFIX ;; *) echo "unknown option $1" usage="yes" ;; esac shift done fi if test "x$usage" = "xyes"; then echo "" echo "Usage:" echo " libval-config [--cflags] [--agent-libs] [--libs] [--version]" echo " ... [see below for complete flag list]" echo "" echo " --version displays the libval version number" echo "" echo " These options produce the various compilation flags needed when" echo " building external SNMP applications:" echo "" echo " --base-cflags lists additional compilation flags needed" echo " --cflags lists additional compilation flags needed" echo " (includes -I. and extra developer warning flags)" echo "" echo " These options produce the various link flags needed when" echo " building external SNMP applications:" echo "" echo " --libs lists libraries needed for building applications" echo "" echo " These options produce various link flags broken down into parts." echo " (Most of the time the simple options above should be used.)" echo "" echo " --libdir path to libval" echo "" echo " --libval-libs libval (with path)" echo "" echo " --ldflags link flags for external libraries" echo " --external-libs external libraries needed by libval" echo "" echo " Details on how the libval package was compiled:" echo "" echo " --configure-options display original configure arguments" echo " --prefix display the installation prefix" echo "" echo " --resolver-config display path to resolver configuration" echo " --root-hints display path to root hints file" echo " --dnsval-config display path to dnsval configuration" exit fi dnsval-2.0/windows.mak0000775000237200023720000001023311732164725015170 0ustar hardakerhardaker# compiler options PERL=perl CC=cl CFLAG= /Zi /nologo /W3 /WX- /Od /Gm /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /MDd CDEFS= /D "i386" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" INC=/I include INC=/I \usr\include /I include SHLIB_CFLAGS=$(CFLAG) $(INC) $(CDEFS) MKDIR=mkdir SRC_D=. LINK=link LFLAGS64=/INCREMENTAL /NOLOGO /opt:ref /debug /DLL /MANIFEST /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X64 LFLAGS32=/INCREMENTAL /NOLOGO /opt:ref /debug /DLL /MANIFEST /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 EX_LIBS=ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib LIB_SSL=/libpath:\usr\lib libeay32.lib ssleay32.lib OUT_D=Debug SRC_LIBSRES_D=libsres TMP_LIBSRES_D=libsres\$(OUT_D) SRC_LIBVAL_D=libval TMP_LIBVAL_D=libval\$(OUT_D) LIBSRES_OBJS = $(TMP_LIBSRES_D)\base64.obj \ $(TMP_LIBSRES_D)\dllmain.obj \ $(TMP_LIBSRES_D)\ns_name.obj \ $(TMP_LIBSRES_D)\ns_netint.obj \ $(TMP_LIBSRES_D)\ns_parse.obj \ $(TMP_LIBSRES_D)\ns_print.obj \ $(TMP_LIBSRES_D)\ns_samedomain.obj \ $(TMP_LIBSRES_D)\ns_ttl.obj \ $(TMP_LIBSRES_D)\nsap_addr.obj \ $(TMP_LIBSRES_D)\res_comp.obj \ $(TMP_LIBSRES_D)\res_debug.obj \ $(TMP_LIBSRES_D)\res_io_manager.obj \ $(TMP_LIBSRES_D)\res_mkquery.obj \ $(TMP_LIBSRES_D)\res_query.obj \ $(TMP_LIBSRES_D)\res_support.obj \ $(TMP_LIBSRES_D)\res_tsig.obj LIBSRES_DLL = $(OUT_D)\libsres.dll LIBVAL_OBJS = $(TMP_LIBVAL_D)\dllmain.obj \ $(TMP_LIBVAL_D)\val_assertion.obj \ $(TMP_LIBVAL_D)\val_cache.obj \ $(TMP_LIBVAL_D)\val_context.obj \ $(TMP_LIBVAL_D)\val_crypto.obj \ $(TMP_LIBVAL_D)\val_get_rrset.obj \ $(TMP_LIBVAL_D)\val_getaddrinfo.obj \ $(TMP_LIBVAL_D)\val_gethostbyname.obj \ $(TMP_LIBVAL_D)\val_log.obj \ $(TMP_LIBVAL_D)\val_parse.obj \ $(TMP_LIBVAL_D)\val_policy.obj \ $(TMP_LIBVAL_D)\val_resquery.obj \ $(TMP_LIBVAL_D)\val_support.obj \ $(TMP_LIBVAL_D)\val_verify.obj \ $(TMP_LIBVAL_D)\val_x_query.obj LIBVAL_DLL = $(OUT_D)\libval.dll all: win64 win32: $(OUT_D) libsres libval dll32 win64: $(OUT_D) libsres libval dll64 libsres: $(TMP_LIBSRES_D) $(LIBSRES_OBJS) libval: $(TMP_LIBVAL_D) $(LIBVAL_OBJS) dll32: libsres32 libval32 dll64: libsres64 libval64 clean: IF EXIST $(OUT_D) rmdir /S /Q $(OUT_D) IF EXIST libsres\$(OUT_D) rmdir /S /Q libsres\$(OUT_D) IF EXIST libval\$(OUT_D) rmdir /S /Q libval\$(OUT_D) banner: @echo building libraries $(OUT_D): $(MKDIR) "$(OUT_D)" $(TMP_LIBSRES_D): $(MKDIR) "$(TMP_LIBSRES_D)" $(TMP_LIBVAL_D): $(MKDIR) "$(TMP_LIBVAL_D)" {$(SRC_LIBSRES_D)}.c{$(TMP_LIBSRES_D)}.obj: $(CC) $(SHLIB_CFLAGS) /Fo$(*R).obj -c $< {$(SRC_LIBVAL_D)}.c{$(TMP_LIBVAL_D)}.obj: $(CC) $(SHLIB_CFLAGS) /EHsc /GS /Fo$(*R).obj -c $< libsres64: $(LIBSRES_OBJS) $(LINK) $(LFLAGS64) /out:$(OUT_D)\libsres.dll @<< $(LIBSRES_OBJS) $(SHLIB_EX_OBJS) $(EX_LIBS) $(LIB_SSL) /DEF:$(SRC_LIBSRES_D)\libsres.def /ManifestFile:"$(TMP_LIBSRES_D)\libsres.dll.intermediate.manifest" << IF EXIST $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 libval64: $(LIBVAL_OBJS) $(LINK) $(LFLAGS64) /out:$(OUT_D)\libval.dll @<< $(LIBVAL_OBJS) $(SHLIB_EX_OBJS) $(EX_LIBS) $(LIB_SSL) $(OUT_D)\libsres.lib /DEF:$(SRC_LIBVAL_D)\libval.def /ManifestFile:"$(TMP_LIBVAL_D)\libval.dll.intermediate.manifest" << IF EXIST $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 libsres32: $(LIBSRES_OBJS) $(LINK) $(LFLAGS32) /out:$(OUT_D)\libsres.dll @<< $(LIBSRES_OBJS) $(SHLIB_EX_OBJS) $(EX_LIBS) $(LIB_SSL) /DEF:$(SRC_LIBSRES_D)\libsres.def /ManifestFile:"$(TMP_LIBSRES_D)\libsres.dll.intermediate.manifest" << IF EXIST $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 libval32: $(LIBVAL_OBJS) $(LINK) $(LFLAGS32) /out:$(OUT_D)\libval.dll @<< $(LIBVAL_OBJS) $(SHLIB_EX_OBJS) $(EX_LIBS) $(LIB_SSL) $(OUT_D)\libsres.lib /DEF:$(SRC_LIBVAL_D)\libval.def /ManifestFile:"$(TMP_LIBVAL_D)\libval.dll.intermediate.manifest" << IF EXIST $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 dnsval-2.0/mkinstalldirs0000775000237200023720000000132010437603413015575 0ustar hardakerhardaker#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs 1664 2006-06-01 15:26:03Z rstory $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here dnsval-2.0/libsres/0000775000237200023720000000000012111172615014432 5ustar hardakerhardakerdnsval-2.0/libsres/nsap_addr.c0000664000237200023720000000525311732713653016551 0ustar hardakerhardaker/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by 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 ISC 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. */ #include "validator-internal.h" #ifndef HAVE_INET_NSAP_NTOA static char xtob(int c) { return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); } u_int inet_nsap_addr(const char *ascii, u_char * binary, int maxlen) { u_char c, nib; u_int len = 0; if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X')) return (0); ascii += 2; while ((c = *ascii++) != '\0' && len < (u_int) maxlen) { if (c == '.' || c == '+' || c == '/') continue; if (!isascii(c)) return (0); if (islower(c)) c = toupper(c); if (isxdigit(c)) { nib = xtob(c); c = *ascii++; if (c != '\0') { c = toupper(c); if (isxdigit(c)) { *binary++ = (nib << 4) | xtob(c); len++; } else return (0); } else return (0); } else return (0); } return (len); } char * inet_nsap_ntoa(int binlen, const u_char * binary, char *ascii) { int nib; int i; char inet_nsap_ntoa_tmpbuf[255 * 3]; char *tmpbuf = inet_nsap_ntoa_tmpbuf; char *start; if (ascii) start = ascii; else { ascii = tmpbuf; start = tmpbuf; } *ascii++ = '0'; *ascii++ = 'x'; if (binlen > 255) binlen = 255; for (i = 0; i < binlen; i++) { nib = *binary >> 4; *ascii++ = nib + (nib < 10 ? '0' : '7'); nib = *binary++ & 0x0f; *ascii++ = nib + (nib < 10 ? '0' : '7'); if (((i % 2) == 0 && (i + 1) < binlen)) *ascii++ = '.'; } *ascii = '\0'; return (start); } #endif /*HAVE_INET_NSAP_NTOA */ /* * ! \file */ dnsval-2.0/libsres/ns_parse.c0000664000237200023720000001473611732713653016436 0ustar hardakerhardaker/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by 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 ISC 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. */ #include "validator-internal.h" #include "res_support.h" #include "res_comp.h" #if HAVE_ARPA_NAMESER_H && !defined(__OpenBSD__) && !defined(eabi) #ifndef STRUCT___NS_MSG_HAS__MSG_PTR # ifdef STRUCT___NS_MSG_HAS__PTR # define _msg_ptr _ptr # else # error "unknown msg ptr member in struct __ns_msg" # endif #endif #endif /* * Forward. */ static void setsection(ns_msg * msg, ns_sect sect); /* * Macros. */ #define RETERR(err) do { errno = (err); return (-1); } while (0) /* * Public. */ /* * These need to be in the same order as the nres.h:ns_flag enum. */ struct _ns_flagdata _ns_flagdata_flags[16] = { {0x8000, 15}, /* qr. */ {0x7800, 11}, /* opcode. */ {0x0400, 10}, /* aa. */ {0x0200, 9}, /* tc. */ {0x0100, 8}, /* rd. */ {0x0080, 7}, /* ra. */ {0x0040, 6}, /* z. */ {0x0020, 5}, /* ad. */ {0x0010, 4}, /* cd. */ {0x000f, 0}, /* rcode. */ {0x0000, 0}, /* expansion (1/6). */ {0x0000, 0}, /* expansion (2/6). */ {0x0000, 0}, /* expansion (3/6). */ {0x0000, 0}, /* expansion (4/6). */ {0x0000, 0}, /* expansion (5/6). */ {0x0000, 0}, /* expansion (6/6). */ }; /* * ns_msg_getflag is a macro on linux, but Solaris and Darwin * both use defines of the function to map to other function * names. * * We rename this function for internal usage */ int libsres_msg_getflag(ns_msg han, int flag) { return (((han)._flags & _ns_flagdata_flags[flag].mask) >> _ns_flagdata_flags[flag]. shift); } int ns_skiprr(const u_char * ptr, const u_char * eom, ns_sect section, int count) { const u_char *optr = ptr; for ((void) NULL; count > 0; count--) { int b, rdlength; b = dn_skipname(ptr, eom); if (b < 0) RETERR(EMSGSIZE); ptr += b /*Name */ + NS_INT16SZ /*Type */ + NS_INT16SZ /*Class */ ; if (section != ns_s_qd) { if (ptr + NS_INT32SZ + NS_INT16SZ > eom) RETERR(EMSGSIZE); ptr += NS_INT32SZ /*TTL*/; RES_GET16(rdlength, ptr); ptr += rdlength /*RData */ ; } } if (ptr > eom) RETERR(EMSGSIZE); return (ptr - optr); } int ns_initparse(const u_char * msg, int msglen, ns_msg * handle) { const u_char *eom = msg + msglen; int i; if ((NULL == msg) || (0 == msglen)) #ifdef ENODATA RETERR(ENODATA); #else RETERR(EINVAL); #endif memset(handle, 0x5e, sizeof(*handle)); handle->_msg = msg; handle->_eom = eom; if (msg + NS_INT16SZ > eom) RETERR(EMSGSIZE); RES_GET16(handle->_id, msg); if (msg + NS_INT16SZ > eom) RETERR(EMSGSIZE); RES_GET16(handle->_flags, msg); for (i = 0; i < ns_s_max; i++) { if (msg + NS_INT16SZ > eom) RETERR(EMSGSIZE); RES_GET16(handle->_counts[i], msg); } for (i = 0; i < ns_s_max; i++) if (handle->_counts[i] == 0) handle->_sections[i] = NULL; else { int b = ns_skiprr(msg, eom, (ns_sect) i, handle->_counts[i]); if (b < 0) return (-1); handle->_sections[i] = msg; msg += b; } if (msg != eom) RETERR(EMSGSIZE); setsection(handle, ns_s_max); return (0); } int ns_parserr(ns_msg * handle, ns_sect section, int rrnum, ns_rr * rr) { int b; int tmp; /* * Make section right. */ if ((tmp = section) < 0 || section >= ns_s_max) RETERR(ENODEV); if (section != handle->_sect) setsection(handle, section); /* * Make rrnum right. */ if (rrnum == -1) rrnum = handle->_rrnum; if (rrnum < 0 || rrnum >= handle->_counts[(int) section]) RETERR(ENODEV); if (rrnum < handle->_rrnum) setsection(handle, section); if (rrnum > handle->_rrnum) { b = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum); if (b < 0) return (-1); handle->_msg_ptr += b; handle->_rrnum = rrnum; } /* * Do the parse. */ b = dn_expand(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME); if (b < 0) return (-1); handle->_msg_ptr += b; if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); RES_GET16(rr->type, handle->_msg_ptr); RES_GET16(rr->rr_class, handle->_msg_ptr); if (section == ns_s_qd) { rr->ttl = 0; rr->rdlength = 0; rr->rdata = NULL; } else { if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) RETERR(EMSGSIZE); RES_GET32(rr->ttl, handle->_msg_ptr); RES_GET16(rr->rdlength, handle->_msg_ptr); if (handle->_msg_ptr + rr->rdlength > handle->_eom) RETERR(EMSGSIZE); rr->rdata = handle->_msg_ptr; handle->_msg_ptr += rr->rdlength; } if (++handle->_rrnum > handle->_counts[(int) section]) setsection(handle, (ns_sect) ((int) section + 1)); /* * All done. */ return (0); } /* * Private. */ static void setsection(ns_msg * msg, ns_sect sect) { msg->_sect = sect; if (sect == ns_s_max) { msg->_rrnum = -1; msg->_msg_ptr = NULL; } else { msg->_rrnum = 0; msg->_msg_ptr = msg->_sections[(int) sect]; } } dnsval-2.0/libsres/res_tsig.h0000664000237200023720000000263511560322751016435 0ustar hardakerhardaker/* * Copyright (c) 1995, 1996, 1997 by Trusted Information Systems, 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 TRUSTED INFORMATION SYSTEMS * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * TRUSTED INFORMATION SYSTEMS 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 THE SOFTWARE. */ #ifndef __RES_TSIG_H__ #define __RES_TSIG_H__ #define SR_TS_UNSET 0 #define SR_TS_OK 1 #define SR_TS_FAIL -2 #define SR_TS_CALL_ERROR -3 int res_tsig_sign(u_char * query, size_t query_length, struct name_server *ns, u_char ** signed_query, size_t *signed_length); int res_tsig_verifies(struct name_server *respondent, u_char * answer, size_t answer_length); #endif dnsval-2.0/libsres/ns_name.c0000664000237200023720000006530011732713653016235 0ustar hardakerhardaker/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by 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 ISC 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. */ #include "validator-internal.h" #define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */ #define DNS_LABELTYPE_BITSTRING 0x41 /* * Data. */ static const char digits[] = "0123456789"; static const char digitvalue[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256 */ }; /* * Forward. */ static int special(int); static int printable(int); static int dn_find(const u_char *, const u_char *, const u_char * const *, const u_char * const *); static int encode_bitsring(const char **, const char *, char **, char **, const char *); static int labellen(const u_char *); static int decode_bitstring(const char **, char *, const char *); /* * Public. */ /* * ns_name_ntop(src, dst, dstsiz) * Convert an encoded domain name to printable ascii as per RFC1035. * return: * Number of bytes written to buffer, or -1 (with errno set) * notes: * The root is returned as "." * All other domains are returned in non absolute form */ int ns_name_ntop(const u_char * src, char *dst, size_t dstsiz) { const u_char *cp; char *dn, *eom; u_char c; u_int n; int l; cp = src; dn = dst; eom = dst + dstsiz; while ((n = *cp++) != 0) { if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* * Some kind of compression pointer. */ errno = EMSGSIZE; return (-1); } if (dn != dst) { if (dn >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = '.'; } if ((l = labellen(cp - 1)) < 0) { errno = EMSGSIZE; /* XXX */ return (-1); } if (dn + l >= eom) { errno = EMSGSIZE; return (-1); } if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { int m; if (n != DNS_LABELTYPE_BITSTRING) { /* * XXX: labellen should reject this case */ errno = EINVAL; return (-1); } if ((m = decode_bitstring((const char **) &cp, dn, eom)) < 0) { errno = EMSGSIZE; return (-1); } dn += m; continue; } for ((void) NULL; l > 0; l--) { c = *cp++; if (special(c)) { if (dn + 1 >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = '\\'; *dn++ = (char) c; } else if (!printable(c)) { if (dn + 3 >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = '\\'; *dn++ = digits[c / 100]; *dn++ = digits[(c % 100) / 10]; *dn++ = digits[c % 10]; } else { if (dn >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = (char) c; } } } if (dn == dst) { if (dn >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = '.'; } if (dn >= eom) { errno = EMSGSIZE; return (-1); } *dn++ = '\0'; return (dn - dst); } /* * ns_name_pton(src, dst, dstsiz) * Convert a ascii string into an encoded domain name as per RFC1035. * return: * -1 if it fails * 1 if string was fully qualified * 0 is string was not fully qualified * notes: * Enforces label and domain length limits. */ int ns_name_pton(const char *src, u_char * dst, size_t dstsiz) { u_char *label, *bp, *eom; int c, n, escaped, e = 0; const char *cp; escaped = 0; bp = dst; eom = dst + dstsiz; label = bp++; while ((c = *src++) != 0) { if (escaped) { if (c == '[') { /* start a bit string label */ if ((cp = strchr(src, ']')) == NULL) { errno = EINVAL; /* ??? */ return (-1); } if ((e = encode_bitsring(&src, cp + 2, (char **) &label, (char **) &bp, (const char *) eom)) != 0) { errno = e; return (-1); } escaped = 0; label = bp++; if ((c = *src++) == 0) goto done; else if (c != '.') { errno = EINVAL; return (-1); } continue; } else if ((cp = strchr(digits, c)) != NULL) { n = (cp - digits) * 100; if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL) { errno = EMSGSIZE; return (-1); } n += (cp - digits) * 10; if ((c = *src++) == 0 || (cp = strchr(digits, c)) == NULL) { errno = EMSGSIZE; return (-1); } n += (cp - digits); if (n > 255) { errno = EMSGSIZE; return (-1); } c = n; } escaped = 0; } else if (c == '\\') { escaped = 1; continue; } else if (c == '.') { c = (bp - label - 1); if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ errno = EMSGSIZE; return (-1); } if (label >= eom) { errno = EMSGSIZE; return (-1); } *label = c; /* * Fully qualified ? */ if (*src == '\0') { if (c != 0) { if (bp >= eom) { errno = EMSGSIZE; return (-1); } *bp++ = '\0'; } if ((bp - dst) > NS_MAXCDNAME) { errno = EMSGSIZE; return (-1); } return (1); } if (c == 0 || *src == '.') { errno = EMSGSIZE; return (-1); } label = bp++; continue; } if (bp >= eom) { errno = EMSGSIZE; return (-1); } *bp++ = (u_char) c; } c = (bp - label - 1); if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ errno = EMSGSIZE; return (-1); } done: if (label >= eom) { errno = EMSGSIZE; return (-1); } *label = c; if (c != 0) { if (bp >= eom) { errno = EMSGSIZE; return (-1); } *bp++ = 0; } if ((bp - dst) > NS_MAXCDNAME) { /* src too big */ errno = EMSGSIZE; return (-1); } return (0); } /* * ns_name_ntol(src, dst, dstsiz) * Convert a network strings labels into all lowercase. * return: * Number of bytes written to buffer, or -1 (with errno set) * notes: * Enforces label and domain length limits. */ int ns_name_ntol(const u_char * src, u_char * dst, size_t dstsiz) { const u_char *cp; u_char *dn, *eom; u_char c; u_int n; int l; cp = src; dn = dst; eom = dst + dstsiz; if (dn >= eom) { errno = EMSGSIZE; return (-1); } while ((n = *cp++) != 0) { if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* * Some kind of compression pointer. */ errno = EMSGSIZE; return (-1); } *dn++ = n; if ((l = labellen(cp - 1)) < 0) { errno = EMSGSIZE; return (-1); } if (dn + l >= eom) { errno = EMSGSIZE; return (-1); } for ((void) NULL; l > 0; l--) { c = *cp++; if (isupper(c)) *dn++ = tolower(c); else *dn++ = c; } } *dn++ = '\0'; return (dn - dst); } /* * ns_name_unpack(msg, eom, src, dst, dstsiz) * Unpack a domain name from a message, source may be compressed. * return: * -1 if it fails, or consumed octets if it succeeds. */ int ns_name_unpack(const u_char * msg, const u_char * eom, const u_char * src, u_char * dst, size_t dstsiz) { const u_char *srcp, *dstlim; u_char *dstp; int n, len, checked, l; len = -1; checked = 0; dstp = dst; srcp = src; dstlim = dst + dstsiz; if (srcp < msg || srcp >= eom) { errno = EMSGSIZE; return (-1); } /* * Fetch next label in domain name. */ while ((n = *srcp++) != 0) { /* * Check for indirection. */ switch (n & NS_CMPRSFLGS) { case 0: case NS_TYPE_ELT: /* * Limit checks. */ if ((l = labellen(srcp - 1)) < 0) { errno = EMSGSIZE; return (-1); } if (dstp + l + 1 >= dstlim || srcp + l >= eom) { errno = EMSGSIZE; return (-1); } checked += l + 1; *dstp++ = n; memcpy(dstp, srcp, l); dstp += l; srcp += l; break; case NS_CMPRSFLGS: if (srcp >= eom) { errno = EMSGSIZE; return (-1); } if (len < 0) len = srcp - src + 1; srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); if (srcp < msg || srcp >= eom) { /* Out of range. */ errno = EMSGSIZE; return (-1); } checked += 2; /* * Check for loops in the compressed name; * if we've looked at the whole message, * there must be a loop. */ if (checked >= eom - msg) { errno = EMSGSIZE; return (-1); } break; default: errno = EMSGSIZE; return (-1); /* flag error */ } } *dstp = '\0'; if (len < 0) len = srcp - src; return (len); } /* * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr) * Pack domain name 'domain' into 'comp_dn'. * return: * Size of the compressed name, or -1. * notes: * 'dnptrs' is an array of pointers to previous compressed names. * dnptrs[0] is a pointer to the beginning of the message. The array * ends with NULL. * 'lastdnptr' is a pointer to the end of the array pointed to * by 'dnptrs'. * Side effects: * The list of pointers in dnptrs is updated for labels inserted into * the message as we compress the name. If 'dnptr' is NULL, we don't * try to compress names. If 'lastdnptr' is NULL, we don't update the * list. */ int ns_name_pack(const u_char * src, u_char * dst, int dstsiz, const u_char ** dnptrs, const u_char ** lastdnptr) { u_char *dstp; const u_char **cpp, **lpp, *eob, *msg; const u_char *srcp; int n, l, first = 1; srcp = src; dstp = dst; eob = dstp + dstsiz; lpp = cpp = NULL; if (dnptrs != NULL) { if ((msg = *dnptrs++) != NULL) { for (cpp = dnptrs; *cpp != NULL; cpp++) (void) NULL; lpp = cpp; /* end of list to search */ } } else msg = NULL; /* * make sure the domain we are about to add is legal */ l = 0; do { int tmp_l; n = *srcp; if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { errno = EMSGSIZE; return (-1); } if ((tmp_l = labellen(srcp)) < 0) { errno = EINVAL; return (-1); } l += tmp_l + 1; if (l > NS_MAXCDNAME) { errno = EMSGSIZE; return (-1); } srcp += tmp_l + 1; } while (n != 0); /* * from here on we need to reset compression pointer array on error */ srcp = src; do { /* * Look to see if we can use pointers. */ n = *srcp; if (n != 0 && msg != NULL) { l = dn_find(srcp, msg, (const u_char * const *) dnptrs, (const u_char * const *) lpp); if (l >= 0) { if (dstp + 1 >= eob) { goto cleanup; } *dstp++ = (l >> 8) | NS_CMPRSFLGS; *dstp++ = l % 256; return (dstp - dst); } /* * Not found, save it. */ if (lastdnptr != NULL && cpp < lastdnptr - 1 && (dstp - msg) < 0x4000 && first) { *cpp++ = dstp; *cpp = NULL; first = 0; } } /* * copy label to buffer */ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* * Should not happen. */ goto cleanup; } n = labellen(srcp); if (dstp + 1 + n >= eob) { goto cleanup; } memcpy(dstp, srcp, n + 1); srcp += n + 1; dstp += n + 1; } while (n != 0); if (dstp > eob) { cleanup: if (msg != NULL) *lpp = NULL; errno = EMSGSIZE; return (-1); } return (dstp - dst); } /* * ns_name_uncompress(msg, eom, src, dst, dstsiz) * Expand compressed domain name to presentation format. * return: * Number of bytes read out of `src', or -1 (with errno set). * note: * Root domain returns as "." not "". */ int ns_name_uncompress(const u_char * msg, const u_char * eom, const u_char * src, char *dst, size_t dstsiz) { u_char tmp[NS_MAXCDNAME]; int n; if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof(tmp))) == -1) return (-1); if (ns_name_ntop(tmp, dst, dstsiz) == -1) return (-1); return (n); } /* * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr) * Compress a domain name into wire format, using compression pointers. * return: * Number of bytes consumed in `dst' or -1 (with errno set). * notes: * 'dnptrs' is an array of pointers to previous compressed names. * dnptrs[0] is a pointer to the beginning of the message. * The list ends with NULL. 'lastdnptr' is a pointer to the end of the * array pointed to by 'dnptrs'. Side effect is to update the list of * pointers for labels inserted into the message as we compress the name. * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' * is NULL, we don't update the list. */ int ns_name_compress(const char *src, u_char * dst, size_t dstsiz, const u_char ** dnptrs, const u_char ** lastdnptr) { u_char tmp[NS_MAXCDNAME]; if (ns_name_pton(src, tmp, sizeof(tmp)) == -1) return (-1); return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr)); } /* * Reset dnptrs so that there are no active references to pointers at or * after src. */ void ns_name_rollback(const u_char * src, const u_char ** dnptrs, const u_char ** lastdnptr) { while (dnptrs < lastdnptr && *dnptrs != NULL) { if (*dnptrs >= src) { *dnptrs = NULL; break; } dnptrs++; } } /* * ns_name_skip(ptrptr, eom) * Advance *ptrptr to skip over the compressed name it points at. * return: * 0 on success, -1 (with errno set) on failure. */ int ns_name_skip(const u_char ** ptrptr, const u_char * eom) { const u_char *cp; u_int n; int l; cp = *ptrptr; while (cp < eom && (n = *cp++) != 0) { /* * Check for indirection. */ switch (n & NS_CMPRSFLGS) { case 0: /* normal case, n == len */ cp += n; continue; case NS_TYPE_ELT: /* EDNS0 extended label */ if ((l = labellen(cp - 1)) < 0) { errno = EMSGSIZE; /* XXX */ return (-1); } cp += l; continue; case NS_CMPRSFLGS: /* indirection */ cp++; break; default: /* illegal type */ errno = EMSGSIZE; return (-1); } break; } if (cp > eom) { errno = EMSGSIZE; return (-1); } *ptrptr = cp; return (0); } /* * Private. */ /* * special(ch) * Thinking in noninternationalized USASCII (per the DNS spec), * is this characted special ("in need of quoting") ? * return: * boolean. */ static int special(int ch) { switch (ch) { case 0x22: /* '"' */ case 0x2E: /* '.' */ case 0x3B: /* ';' */ case 0x5C: /* '\\' */ case 0x28: /* '(' */ case 0x29: /* ')' */ /* * Special modifiers in zone files. */ case 0x40: /* '@' */ case 0x24: /* '$' */ return (1); default: return (0); } } /* * printable(ch) * Thinking in noninternationalized USASCII (per the DNS spec), * is this character visible and not a space when printed ? * return: * boolean. */ static int printable(int ch) { return (ch > 0x20 && ch < 0x7f); } /* * Thinking in noninternationalized USASCII (per the DNS spec), * convert this character to lower case if it's upper case. */ static int mklower(int ch) { if (ch >= 0x41 && ch <= 0x5A) return (ch + 0x20); return (ch); } /* * dn_find(domain, msg, dnptrs, lastdnptr) * Search for the counted-label name in an array of compressed names. * return: * offset from msg if found, or -1. * notes: * dnptrs is the pointer to the first name on the list, * not the pointer to the start of the message. */ static int dn_find(const u_char * domain, const u_char * msg, const u_char * const *dnptrs, const u_char * const *lastdnptr) { const u_char *dn, *cp, *sp; const u_char *const *cpp; u_int n; for (cpp = dnptrs; cpp < lastdnptr; cpp++) { sp = *cpp; /* * terminate search on: * root label * compression pointer * unusable offset */ while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 && (sp - msg) < 0x4000) { dn = domain; cp = sp; while ((n = *cp++) != 0) { /* * check for indirection */ switch (n & NS_CMPRSFLGS) { case 0: /* normal case, n == len */ n = labellen(cp - 1); /* XXX */ if (n != *dn++) goto next; for ((void) NULL; n > 0; n--) if (mklower(*dn++) != mklower(*cp++)) goto next; /* * Is next root for both ? */ if (*dn == '\0' && *cp == '\0') return (sp - msg); if (*dn) continue; goto next; case NS_CMPRSFLGS: /* indirection */ cp = msg + (((n & 0x3f) << 8) | *cp); break; default: /* illegal type */ errno = EMSGSIZE; return (-1); } } next:; sp += *sp + 1; } } errno = ENOENT; return (-1); } static int decode_bitstring(const char **cpp, char *dn, const char *eom) { const char *cp = *cpp; char *beg = dn, tc; int b, blen, plen, i; if ((blen = (*cp & 0xff)) == 0) blen = 256; plen = (blen + 3) / 4; plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); if (dn + plen >= eom) return (-1); cp++; i = SPRINTF((dn, "\\[x")); if (i < 0) return (-1); dn += i; for (b = blen; b > 7; b -= 8, cp++) { i = SPRINTF((dn, "%02x", *cp & 0xff)); if (i < 0) return (-1); dn += i; } if (b > 4) { tc = *cp++; i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b)))); if (i < 0) return (-1); dn += i; } else if (b > 0) { tc = *cp++; i = SPRINTF((dn, "%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); if (i < 0) return (-1); dn += i; } i = SPRINTF((dn, "/%d]", blen)); if (i < 0) return (-1); dn += i; *cpp = cp; return (dn - beg); } static int encode_bitsring(const char **bp, const char *end, char **labelp, char **dst, const char *eom) { int afterslash = 0; const char *cp = *bp; char *tp, c; const char *beg_blen; char *end_blen = NULL; int value = 0, count = 0, tbcount = 0, blen = 0; beg_blen = end_blen = NULL; /* * a bitstring must contain at least 2 characters */ if (end - cp < 2) return (EINVAL); /* * XXX: currently, only hex strings are supported */ if (*cp++ != 'x') return (EINVAL); if (!isxdigit((*cp) & 0xff)) /* reject '\[x/BLEN]' */ return (EINVAL); for (tp = *dst + 1; cp < end && tp < eom; cp++) { switch ((c = *cp)) { case ']': /* end of the bitstring */ if (afterslash) { if (beg_blen == NULL) return (EINVAL); blen = (int) strtol(beg_blen, &end_blen, 10); if (*end_blen != ']') return (EINVAL); } if (count) *tp++ = ((value << 4) & 0xff); cp++; /* skip ']' */ goto done; case '/': afterslash = 1; break; default: if (afterslash) { if (!isdigit(c & 0xff)) return (EINVAL); if (beg_blen == NULL) { if (c == '0') { /* * blen never begings with 0 */ return (EINVAL); } beg_blen = cp; } } else { if (!isxdigit(c & 0xff)) return (EINVAL); value <<= 4; value += digitvalue[(int) c]; count += 4; tbcount += 4; if (tbcount > 256) return (EINVAL); if (count == 8) { *tp++ = value; count = 0; } } break; } } done: if (cp >= end || tp >= eom) return (EMSGSIZE); /* * bit length validation: * If a is present, the number of digits in the * MUST be just sufficient to contain the number of bits specified * by the . If there are insignificant bits in a final * hexadecimal or octal digit, they MUST be zero. * RFC 2673, Section 3.2. */ if (blen > 0) { int traillen; if (((blen + 3) & ~3) != tbcount) return (EINVAL); traillen = tbcount - blen; /* between 0 and 3 */ if (((value << (8 - traillen)) & 0xff) != 0) return (EINVAL); } else blen = tbcount; if (blen == 256) blen = 0; /* * encode the type and the significant bit fields */ **labelp = DNS_LABELTYPE_BITSTRING; **dst = blen; *bp = cp; *dst = tp; return (0); } static int labellen(const u_char * lp) { int bitlen; u_char l = *lp; if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { /* * should be avoided by the caller */ return (-1); } if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { if (l == DNS_LABELTYPE_BITSTRING) { if ((bitlen = *(lp + 1)) == 0) bitlen = 256; return ((bitlen + 7) / 8 + 1); } return (-1); /* unknwon ELT */ } return (l); } dnsval-2.0/libsres/dllmain.c0000775000237200023720000000102411732136442016224 0ustar hardakerhardaker// dllmain.cpp : Defines the entry point for the DLL application. #include #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } dnsval-2.0/libsres/.cvsignore0000664000237200023720000000004410424167717016444 0ustar hardakerhardakerMakefile *.lo *.la .libs cscope.out dnsval-2.0/libsres/ns_samedomain.c0000664000237200023720000001254211732713653017432 0ustar hardakerhardaker/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995,1999 by 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 ISC 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. */ #include "validator-internal.h" /* * int * ns_samedomain(a, b) * Check whether a name belongs to a domain. * Inputs: * a - the domain whose ancestory is being verified * b - the potential ancestor we're checking against * Return: * boolean - is a at or below b? * Notes: * Trailing dots are first removed from name and domain. * Always compare complete subdomains, not only whether the * domain name is the trailing string of the given name. * * "host.foobar.top" lies in "foobar.top" and in "top" and in "" * but NOT in "bar.top" */ int ns_samedomain(const char *a, const char *b) { size_t la, lb; int diff, i, escaped; const char *cp; la = strlen(a); lb = strlen(b); /* * Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */ if (la != 0U && a[la - 1] == '.') { escaped = 0; /** Note this loop doesn't get executed if la==1. */ for (i = la - 2; i >= 0; i--) if (a[i] == '\\') { if (escaped) escaped = 0; else escaped = 1; } else break; if (!escaped) la--; } /* * Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */ if (lb != 0U && b[lb - 1] == '.') { escaped = 0; /** note this loop doesn't get executed if lb==1 */ for (i = lb - 2; i >= 0; i--) if (b[i] == '\\') { if (escaped) escaped = 0; else escaped = 1; } else break; if (!escaped) lb--; } /* * lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */ if (lb == 0U) return (1); /* * 'b' longer than 'a' means 'a' can't be in 'b'. */ if (lb > la) return (0); /* * 'a' and 'b' being equal at this point indicates sameness. */ if (lb == la) return (strncasecmp(a, b, lb) == 0); /* * Ok, we know la > lb. */ diff = la - lb; /* * If 'a' is only 1 character longer than 'b', then it can't be * a subdomain of 'b' (because of the need for the '.' label * separator). */ if (diff < 2) return (0); /* * If the character before the last 'lb' characters of 'b' * isn't '.', then it can't be a match (this lets us avoid * having "foobar.com" match "bar.com"). */ if (a[diff - 1] != '.') return (0); /* * We're not sure about that '.', however. It could be escaped * and thus not a really a label separator. */ escaped = 0; for (i = diff - 2; i >= 0; i--) if (a[i] == '\\') { if (escaped) escaped = 0; else escaped = 1; } else break; if (escaped) return (0); /* * Now compare aligned trailing substring. */ cp = a + diff; return (strncasecmp(cp, b, lb) == 0); } /* * int * ns_makecanon(src, dst, dstsize) * make a canonical copy of domain name "src" * notes: * foo -> foo. * foo. -> foo. * foo.. -> foo. * foo\. -> foo\.. * foo\\. -> foo\\. */ int ns_makecanon(const char *src, char *dst, size_t dstsize) { size_t n = strlen(src); if (n + sizeof(".") > dstsize) { /* Note: sizeof == 2 */ errno = EMSGSIZE; return (-1); } strcpy(dst, src); while (n >= 1U && dst[n - 1] == '.') /* Ends in "." */ if (n >= 2U && dst[n - 2] == '\\' && /* Ends in "\." */ (n < 3U || dst[n - 3] != '\\')) /* But not "\\." */ break; else dst[--n] = '\0'; dst[n++] = '.'; dst[n] = '\0'; return (0); } /* * int * ns_samename(a, b) * determine whether domain name "a" is the same as domain name "b" * return: * -1 on error * 0 if names differ * 1 if names are the same */ int ns_samename(const char *a, const char *b) { char ta[NS_MAXDNAME], tb[NS_MAXDNAME]; if (ns_makecanon(a, ta, sizeof(ta)) < 0 || ns_makecanon(b, tb, sizeof(tb)) < 0) return (-1); if (strncasecmp(ta, tb, NS_MAXDNAME) == 0) return (1); else return (0); } /* * int * ns_subdomain(a, b) * is "a" a subdomain of "b"? */ int ns_subdomain(const char *a, const char *b) { return (ns_samename(a, b) != 1 && ns_samedomain(a, b)); } dnsval-2.0/libsres/res_comp.c0000664000237200023720000001716111732713653016426 0ustar hardakerhardaker/* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * 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, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (c) 1996-1999 by 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 ISC 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. */ #include "validator-internal.h" /* * Expand compressed domain name 'src' to full domain name. * 'msg' is a pointer to the begining of the message, * 'eom' points to the first location after the message, * 'dst' is a pointer to a buffer of size 'dstsiz' for the result. * Return size of compressed name or -1 if there was an error. */ int dn_expand(const u_char * msg, const u_char * eom, const u_char * src, char *dst, int dstsiz) { int n = ns_name_uncompress(msg, eom, src, dst, (size_t) dstsiz); if (n > 0 && dst[0] == '.') dst[0] = '\0'; return (n); } /* * Pack domain name 'exp_dn' in presentation form into 'comp_dn'. * Return the size of the compressed name or -1. * 'length' is the size of the array pointed to by 'comp_dn'. */ int dn_comp(const char *src, u_char * dst, int dstsiz, u_char ** dnptrs, u_char ** lastdnptr) { return (ns_name_compress(src, dst, (size_t) dstsiz, (const u_char **) dnptrs, (const u_char **) lastdnptr)); } /* * Skip over a compressed domain name. Return the size or -1. */ int dn_skipname(const u_char * ptr, const u_char * eom) { const u_char *saveptr = ptr; if (ns_name_skip(&ptr, eom) == -1) return (-1); return (ptr - saveptr); } /* * Verify that a domain name uses an acceptable character set. */ /* * Note the conspicuous absence of ctype macros in these definitions. On * non-ASCII hosts, we can't depend on string literals or ctype macros to * tell us anything about network-format data. The rest of the BIND system * is not careful about this, but for some reason, we're doing it right here. */ #define PERIOD 0x2e #define hyphenchar(c) ((c) == 0x2d) #define bslashchar(c) ((c) == 0x5c) #define periodchar(c) ((c) == PERIOD) #define asterchar(c) ((c) == 0x2a) #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ || ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c)) #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) int res_hnok(const char *dn) { int pch = PERIOD, ch = *dn++; while (ch != '\0') { int nch = *dn++; if (periodchar(ch)) { (void) NULL; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); } else if (periodchar(nch) || nch == '\0') { if (!borderchar(ch)) return (0); } else { if (!middlechar(ch)) return (0); } pch = ch, ch = nch; } return (1); } /* * hostname-like (A, MX, WKS) owners can have "*" as their first label * but must otherwise be as a host name. */ int res_ownok(const char *dn) { if (asterchar(dn[0])) { if (periodchar(dn[1])) return (res_hnok(dn + 2)); if (dn[1] == '\0') return (1); } return (res_hnok(dn)); } /* * SOA RNAMEs and RP RNAMEs can have any printable character in their first * label, but the rest of the name has to look like a host name. */ int res_mailok(const char *dn) { int ch, escaped = 0; /* * "." is a valid missing representation */ if (*dn == '\0') return (1); /* * otherwise